Hibernate中用到了緩存的概念,那麼什麼是緩存呢?這裡介紹的緩存并不是指計算機的記憶體或者CPU的一二級緩存,這裡的緩存是指為了降低程式對實體資料源通路的頻次,進而提高程式運作性能的一種政策。
一級緩存:
首先我們來看下面這個例子。
@Test
public void testCache() {
Session session = getSession();
Employee emp = session.get(Employee.class, 1);
System.out.println(emp.getEmpname());
emp = session.get(Employee.class, 1);
System.out.println(emp.getEmpname());
}
(截圖上傳出現問題)
可以看到控制台隻列印了一次查詢的SQL,這說明用Session第一次查詢到empid為1的對象之後這個對象被緩存起來了,第二次查詢的時候直接從緩存中擷取相應的對象,而不是再查一次資料庫。這個例子表明Hibernate的緩存是與Session有關的。
二級緩存:
Hibernate的二級緩存不是預設的,它不由架構包含而是由第三方元件提供,是一個可插拔式緩存,Hibernate預設提供了一種緩存元件EHCache,同時還支援其他的二級緩存元件,例如Hashtable、OSCache等;二級緩存又稱為“全局緩存”、“應用級緩存”,它的資料可适用範圍是目前應用的所有會話,這與一級緩存隻适用于目前會話内不同。下面我們來看看EHCache的使用。
使用EHCache分為下面幾個步驟:
1、引入對應的jar包;
2、在hibernate.cfg.xml檔案中添加相應的配置;
3、添加ehcache.xml配置檔案;
4、在需要緩存的表對應的映射檔案中添加<cache/>标簽。
首先我們需要導入相應的jar包,要使用EHCache,需要在pom.xml檔案中添加下面兩個依賴。
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>2.10.2</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-ehcache</artifactId>
<version>5.2.3.Final</version>
</dependency>
接下來我們需要在hibernate.cfg.xml中添加相應的配置,我們需要添加如下配置
<property name="hibernate.cache.use_second_level_cache">true</property>
<property name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property>
<property name="hibernate.cache.provider_class">net.sf.ehcache.hibernate.EhCacheProvider</property>
在這裡需要注意一下Hibernate 4.0及以後的需要按照上面的配置,而Hibernate 3.3 的配置是這樣的
<property name="hibernate.cache.use_second_level_cache">true</property>
<property name="cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
然後我們需要添加ehcache.xml配置檔案,這個配置檔案要放在src目錄下
<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="ehcache.xsd">
<diskStore path="java.io.tmpdir"/>
<defaultCache maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="30" timeToLiveSeconds="30" overflowToDisk="false"/>
<!--
配置自定義緩存
maxElementsInMemory:緩存中允許建立的最大對象數
eternal:緩存中對象是否為永久的,如果是,逾時設定将被忽略,對象從不過期。
timeToIdleSeconds:緩存資料的鈍化時間,也就是在一個元素消亡之前,
兩次通路時間的最大時間間隔值,這隻能在元素不是永久駐留時有效,
如果該值是 0 就意味着元素可以停頓無窮長的時間。
timeToLiveSeconds:緩存資料的生存時間,也就是一個元素從建構到消亡的最大時間間隔值,
這隻能在元素不是永久駐留時有效,如果該值是0就意味着元素可以停頓無窮長的時間。
overflowToDisk:記憶體不足時,是否啟用磁盤緩存。
memoryStoreEvictionPolicy:緩存滿了之後的淘汰算法。
-->
<cache name="Employee"
maxElementsInMemory="10000"
eternal="false"
overflowToDisk="false"
timeToIdleSeconds="900"
timeToLiveSeconds="1800"
memoryStoreEvictionPolicy="LFU" />
</ehcache>
最後我們需要在需要緩存的表對應的映射檔案中添加<cache/>标簽,在這個例子中我們要對Employee進行緩存,是以我們在Employee.hbm.xml檔案中添加如下内容。
<cache usage="read-only" include="all" region="Employee"/>
其中usage屬性指定緩存政策,可選的政策包括transactional,read-only,read-write和nonstrict-read-write;region屬性指定二級緩存區域名,指定了二級緩存區域名之後就可以在ehcache.xml中配置相應的自定義緩存了;include表示指定是否緩存延遲加載的對象,all表示緩存所有對象,non-lazy表示不緩存延遲加載的對象。
@Test
session = getSession();
emp = session.get(Employee.class, 1);
System.out.println(emp.getEmpname());