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(); } }