Hibernate之二级缓存
一.简介
Gaving King曾经对别人说,hibernate最耀眼之处是hibernate的缓存机制。Hibernate为了降低应用程序对物理数据源的访问,使用了缓存机制。Hibernate缓存包括一级缓存和二级缓存。一级缓存又称"Session的缓存",是不能被卸载的。本文笔者为大家介绍的是Hibernate的二级缓存。
二.二级缓存
Hibernate的二级缓存又称为"SessionFactory的缓存",由于SessionFactory对象的生命周期和应用的整个过程对应,他是可选的,是一个可配置的插件,默认情况下SessionFactory不会启用这个插件。Hibernate5.2提供了org.
hibernate.cache.ehcache.EhCacheRegionFactory类,它充当缓存插件与Hibernate之间的适配器。
那么什么样的数据适合放在二级缓存中呢?
A.很少被修改的数据
B.不是很重要的数据
C.不会被并发访问的数据
C.常量数据
那么什么样的数据不适合放在二级缓存中呢?
A.经常被修改的数据
B.绝对不允许出现并发访问的数据。如财务数据,绝对不允许出现并发
C.与其他应用共享的数据
三.二级缓存的实现
3.1 hibernate.cfg.xml中加入以下配置
<!-- 是否开启二级缓存 --> <property name="cache.use_query_cache">true</property> <!-- 配置二级缓存的所需的类 --> <property name="cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property> <!-- 配置启用查询缓存--> <property name="cache.use_query_cache">true</property>
3.2 POJO类的注解形式实现
@Entity @Table(name="emp") @Cacheable(value=true) @Cache(usage=CacheConcurrencyStrategy.READ_ONLY) public class Employee { @Id @Column(name="empno") @GenericGenerator(name="assignedGenerator", strategy="assigned") @GeneratedValue(generator="assignedGenerator") private int id; @Column(name="ename") private String ename; @Column(name="job") private String job; @Column(name="hiredate") private Date hiredate; @Column(name="sal") private Double salary; @Column(name="comm") private Double comm; //setter and getter }
3.3 缓存文件
在src目录下建立一个文件,名字叫做encache.xml,文件的类容如下
<ehcache> <diskStore path="d:/hibernateCache"/> <defaultCache maxElementsInMemory="10" eternal="false" timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="true"/> <cache name="com.demo.hibernate.one2many.Employee" maxElementsInMemory="10" eternal="false" timeToIdleSeconds="300" timeToLiveSeconds="600" overflowToDisk="true"/> </ehcache>
3.4 测试
public class HibernateQBCTest { private SessionFactory sf; @Before public void getSessionFactory(){ sf = OracleSessionUtils.getSessionFactory(); } //查询所有 @Test public void list(){ Session session = sf.openSession(); Transaction tx = session.beginTransaction(); List<Employee> empList = session.createCriteria(Employee.class).list(); for(Employee e : empList){ System.out.println(e.getEname()); } tx.commit(); session.close(); //以下查询不会发送SQL Session session1 = sf.openSession(); Transaction tx1 = session1.beginTransaction(); Employee e = session1.get(Employee.class, 7369); System.out.println(e.getEname()); tx1.commit(); session1.close(); } }