Hibernate一级缓存
1.缓存
缓存:是一种优化的方式,将数据存入到内存中,使用的时候直接从内存中读取,不用通过 存储源
Hibernate 一级缓存
- Hibernate提供了优化手段:缓存,抓取…等手段
- 一级缓存:Session级别的缓存,一级缓存的生命周期与Session一致(一级缓存是由一系列java集合构成,一级缓存是自带的,不可卸载),属于事务级缓冲
- 二级缓存:SessionFactory级别的缓存,有的Session共享同一个二级Cache,是一个插件,默认不开启,需要自己配置(重量级缓存,开发中一般用redis代替)
一级缓存的主要两个集合:
private transient ActionQueue activeQueue;
private transient StatePresistenceContext persistenceContext;
//被transient修饰的对象不能被序列化
一级缓存的特点
1. 当应用程序调用Session接口的Save(),update(),saveOrUpdate()等方法保存或更新对象数据时,如果Session中没有相应的对象,Hibernate会自动将数据写入数据库,加入到一级缓存中,如果缓存中有相应的对象,则会将缓存中数据进行修改,在事务提交时写入数据库
2. 当调用Session接口的get().load(),以及Query接口的list(),*iterator()*方法,查询数据时,会首先判断缓存中是否存在该对象,如果已经存在,直接返回该对象信息,如果没有就进入数据库查询,并将对象信息放入缓存中,以便下一次使用
3. close()关闭缓存(无法再进行session的任何操作)
clear(),清空缓存,
evict(Object) 将指定对象从缓存中驱逐
一级缓存验证:
@Test
public void test_Cache(){
//1.得到session
Session session = HibernateUtils.openSession();
//2.开启事务
Transaction ts = session.beginTransaction();
//3.执行操作
//发送sql语句,从数据中将对象查出,放入缓存中
Customer customer1 = session.get(Customer.class, 5L);
System.out.println(customer1);
//不发送sql语句,直接从缓存中拿取对象信息
Customer customer2 = session.get(Customer.class, 5L);
System.out.println(customer2);
System.out.println(customer1 == customer2); //true 两个对象对应一块存储空间
//4.提交事务
ts.commit();
//5.释放资源
session.close();
//报错:Session is closed 无法在对Session做任何操作
Customer customer3 = session.get(Customer.class, 5L);
System.out.println(customer3);
}
一级缓存快照区
一级缓存特殊区域—快照区:用于保留未修改前的对象信息—在对象被放入一级缓中的同时,对象会被拍一张"快照",做一个备份,放入快照区,当事务被提交时,hibernate会自动将缓存中的对象信息与快照中的对(之前数据的备份)象信息进行对比。
- 如果二者数据不相同,就向数据库发送sql语句,对数据库中的记录进行更新,同时*更新快照区的对象信息
- 如果一样,则不发送sql语句,不做任何动作。
eclipse Debug 查找快照区与缓存区
session--> persistenceContext --> entitvEntrvContext --->head
entitvEntrv --> loadState 快照区
entitvInstance 缓存区