一级缓存,就是Session缓存。多个session不能共享一级缓存,因它会伴随session生命周期的创建和消毁。
现象回顾:
测试一级缓存:
同样 session同样的请求,第一次查询:生成SQL语句,第二次查询不生存SQL语句,直接从session缓存取。
测试如下所示:
public void testOneCache(){
Session session = HibernateUtils.openSession();
//第一次查询,找DB,打印SQL
BookTypeEntity bookTypeEntity = session.get(BookTypeEntity.class, 31L);
System.out.println(bookTypeEntity.getTypeName());
// 第二次查询,直接找缓存,不到DB,不打印SQL
BookTypeEntity bookTypeEntity2 = session.get(BookTypeEntity.class, 31L);
System.out.println(bookTypeEntity2.getTypeName());
session.clear();//清空缓存
// 第三次查询,直接找缓存没记录,找DB,打印SQL
BookTypeEntity bookTypeEntity3 = session.get(BookTypeEntity.class, 31L);
System.out.println(bookTypeEntity3.getTypeName());
session.close();
}
特性:减少访问DB提升性能
手工干预缓存 evict() 和 clear()
evict() : 用于将某个对象从Session的一级缓存中清除
1.不需要该对象进行同步的数据更新
2.在批量更新时,当更新删除每一个对象后,要释放此对象所占用的内存.
clear() :用于将一级缓存中的所有对象全部清除。
清楚缓存后,再次同样请求查询,走数据库查询。
当我们查询出来的对象是同一个对象的时候,这个时候我们调用evict(bookType) 这个时候 删除的是全部对象
//清空某一个对象
session.evict(bookType);
//在一级缓存中存储的bookType,bookType2都是39对应的记录,是一个记录。
快照机制(扩展了解)
快照机制(扩展了解)
当执行 commit() 时,Hibernate同时会执行 flush() 方法,hibernate会清理session的一级缓存(flush),也就是将堆内存中的数据与快照中的数据进行对比,如果不一致,则会执行同步(update)操作,若相同,则不执行update。
快照是数据的副本
快照属于一级缓存
快照是在堆内存中的
快照的作用:保证数据一致性
Ex:
Customer cust = session.get(Customer.class, 1L);
cust.setName("汤姆");//修改cust的数据
//session.update(cust);//不执行update语句可以修改数据
tx.commit();