二级缓存&查询缓存
属于SessionFactory级别的缓存,可以在多个session之间共享数据。
image.png实用场合
1.公开的数据, 数据基本上不发生变化
2.该数据保密性不是很强
3.需要引入第三 方的缓存工具,如 EhCache 等。
生命周期
二级缓存的生命周期和sessionFactory是一致的。
开发流程
1.1. 第一步:开启二级缓存
别忘记依赖
image.png
在核心配置hibernate.cfg.xml新增
<property name="hibernate.cache.use_second_level_cache">true</property>
启用二级缓存,hibernate 二级缓存是一个规范接口,没有实现
1.2. 第二步:指定二级缓存实现厂商
在核心配置hibernate.cfg.xml新增,实现厂商。
设置二级缓存的供应商 Idea中没有这个key的提示需手动输入
<property name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property>
1.3. 第三步:在映射文件中开启具体的缓存支持
*.hbm.xml中指定哪个类开启二级缓存
二级缓存一般设置为只读
二级缓存缓存的仅仅是对象,如果查询出来的是对象的一部分属性(返回Object[]),则不会加到缓存中去。
1.4. 第四步:开发
第一次查询,从DB取记录,关闭Session.第二次新 session查询,没有走DB,直接从二级缓存取得记录。
public void testTwoCache(){
Session session1 = HibernateUtils.openSession();
Session session2 = HibernateUtils.openSession();
BookTypeEntity bookTypeEntity = session1.get(BookTypeEntity.class, 31L);
System.out.println(bookTypeEntity.getTypeName());
session1.close();
//第二次查询 走二级缓存,不查DB
BookTypeEntity bookTypeEntity2 = session2.get(BookTypeEntity.class, 31L);
System.out.println(bookTypeEntity2.getTypeName());
session2.close();
}
注意:这里的POJO可以不用序列化。但是如果这个对象需要存储到具体的硬盘中的时候,是需要序列化。
注意:测试二级缓存需要保持关联表为默认的延迟检索机制lazy=true,因为加载关联表二级缓存支持不够。
不足: 二级缓存对于立即加载的支持还是很差的
image.png
测试:
image.png
现象:
第二次查询还是发生的SQL查询。
二级缓存不足:
1,非对象不存储
查询返回的不是对象,下面的HQL不会加载到二级缓存
Select stuName from StudentInfo
2,关联支持不太好
二级缓存,不能很好解决关联表问题。需要把所有关联的地方改为默认的延迟检索,不找关联表。
主要是主表的二级缓存需保持默认lazy="true“
若关联表两边都设置为false,部分到二级缓存,有不成功的地方。
测试:session.get(BookInfo.class, 18L)
3,不支持Query查询
from BookInfo where bookId=:bookId
两次都是从数据库找记录
查询缓存
也是二级缓存,支持Query
查询缓存也是sessionFactory级别的缓存:需要在二级缓存设置的基础上添加
只有当HQL语句完全相同,参数设置也相同才生效
生命周期:只要一些数据放入到查询缓存中,该缓存会一直存在,直到缓存中的数据被修改了,该缓存的生命周期就结束了。
2.1. 第一步:前提条件
同上,必须先配置二级缓存
2.2. 第二步:开启查询缓存
在核心配置Hibernate.cfg.xml中加入
<property name="hibernate.cache.use_query_cache">true</property>
2.3. 第三步:开发的时候需要设置查询缓存
HQL语句后设置开启
query.setCacheable(true);//开启查询缓存
注意保持默认的lazy=true(避免关联)
代码:
public void testQueyCache(){
Session session1 = HibernateUtils.openSession();
Session session2 = HibernateUtils.openSession();
String hql = "from BookTypeEntity where typeId=:tid";
Query<BookTypeEntity> query = session1.createQuery(hql, BookTypeEntity.class);
query.setParameter("tid",31L);
//开启查询缓存
query.setCacheable(true);
BookTypeEntity singleResult = query.getSingleResult();//获取单条记录
System.out.println(singleResult.getTypeName());
session1.close();
//第二次查询
Query<BookTypeEntity> query2 = session2.createQuery(hql, BookTypeEntity.class);
query2.setParameter("tid",31L);
//开启查询缓存
query2.setCacheable(true);
BookTypeEntity singleResult2 = query2.getSingleResult();//获取单条记录
System.out.println(singleResult2.getTypeName());
session2.close();
}
若修改数据或修改HQL的参数,查询缓存不生效.
查询缓存就是让Query可以从二级缓存获得内容。仅主表非关联信息。
必须保持默认的延迟检索方式。