二级缓存有四种缓存区域 :
1.类缓存区域
比如:session.get(Customer.class,1); //这就是类缓存区域
2.集合缓存区域
customer.getOrders(); //就是存放Orders集合的内容的缓存区域就叫集合缓存区域
3.更新时间戳区域
4.查询缓存区域
这几个在后面会详细讲到,现在不讲,想直接看的就跳过看后面测试实例。
一丶类缓存区域
类缓存区域,通过id查询到的对象,就将其放入类缓存区域,其区域中缓存的不是PO对象,而是单独的一些属性值,当从缓存中获取数据,会封装一个新的对象返回(下面会验证)。
1.配置
2.测试
3.测试结果
二丶集合缓存区域
比如这个Customer-orders的例子中,Customer.getOrderSet(); 这查询出来的就将其放入集合缓存区域,从集合缓存中获得内容时,只能获得oid的值,然后从类缓存中查找。所以集合级别的缓存依赖于类级别的缓存;
原理:
1.配置
2.测试
3.测试结果
3.查询 缓存
将HQL语句与 查询结果进行绑定。通过HQL相同语句可以缓存内容。
1.配置
2.测试
3.测试结果
3.时间搓缓存
存放了对于查询结果相关的表进行插入,更新,删除操作的时间戳,Hibernate通过时间戳缓存区域来判断被缓存的查询结果是否过期,如果过期了则从数据库中拿数据,没过期则直接从缓存中拿数据。通俗点讲,就三步
1、查询结果放到二级缓存中,此时记录一个时间为T1
2、当有操作直接更改了数据库的数据时,比如使用hql语句,就会直接对数据库进行修改,而不会改变缓存中的数据。此时记录时间为T2
3、当下次在查询记录时,会先将T1和T2进行比较,如果T2>T1,则说明缓存中的数据不是最新的,那么就从数据库中拿出正确的数据,如果T2=T1,就说明没有对数据库进行过什么修改操作,那么就可以直接从缓存中获取数据。
解惑:如果没有T1和T2的比较,那么会出现我们查询到的数据不是准确的,因为就像上面第二步所说的,数据库的数据会和缓存中的数据不一样,什么读不做就从缓存中拿数据,就会出现错误。
1.配置
无配置
2.测试
3.测试结果
注意几点:
1.注意get/load可以从二级缓存中获取数据,而query的list不能从二级缓存获取数据,但是其查询结果会存入二级缓存。
2.一级缓存是同步二级缓存
注意:如果是用hql来更新修改name,那么就不会同步二级缓存,连一级缓存中的数据也不会改变,hql是直接针对数据库来进行修改的,而set()方法是通过hibernate中的快照区,而不是直接对数据库进行操作。