Hibernate ehcache配置二級緩存
1、首先設置EhCache,建立配置文件ehcache.xml,默認的位置在class-path,可以放到你的src目錄下:
<?xml version="1.0" encoding="UTF-8"?>
<ehcache>
<diskStore path="java.io.tmpdir"/>
<defaultCache
maxElementsInMemory="10000"<!-- 緩存最大數目 -->
eternal="false"<!-- 緩存是否持久 -->
overflowToDisk="true"<!-- 是否保存到磁盤,當系統當機時-->
timeToIdleSeconds="300"<!-- 當緩存閑置n秒后銷毀 -->
timeToLiveSeconds="180"<!-- 當緩存存活n秒后銷毀-->
diskPersistent="false"
diskExpiryThreadIntervalSeconds= "120"/>
</ehcache>
2、在Hibernate配置文件中設置:
<!-- 設置Hibernate的緩存接口類,這個類在Hibernate包中 -->
<property name="cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
<!-- 是否使用查詢緩存 -->
<property name="hibernate.cache.use_query_cache">true</property>
如果使用spring調用Hibernate的sessionFactory的話,這樣設置:
<!--HibernateSession工廠管理 -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource">
<ref bean="datasource" />
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.Oracle9Dialect</prop>
? <prop key="connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.cache.use_query_cache">true</prop>
<prop key="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</prop>
</props>
</property>
<property name="mappingDirectoryLocations">
<list>
<value>/WEB-INF/classes/cn/rmic/manager/hibernate/</value>
</list>
</property>
</bean>
說明一下:如果不設置“查詢緩存”,那么hibernate只會緩存使用load()方法獲得的單個持久化對象,如果想緩存使用findall()、
list()、Iterator()、createCriteria()、createQuery()等方法獲得的數據結果集的話,就需要設置
hibernate.cache.use_query_cache true 才行
3、在Hbm文件中添加<cache usage="read-only"/>
4、如果需要“查詢緩存”,還需要在使用Query或Criteria()時設置其setCacheable(true);屬性
5、實踐出真知,給一段測試程序,如果成功的話第二次查詢時不會讀取數據庫
package cn.rmic.hibernatesample;
import java.util.List;
import org.hibernate.CacheMode;
import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.Session;
import cn.rmic.hibernatesample.hibernate.HibernateSessionFactory;
import cn.rmic.manager.po.Resources;
public class testCacheSelectList ...{
public static void main(String[] args) ...{
Session s=HibernateSessionFactory.getSession();
Criteria c=s.createCriteria(Resources.class);
c.setCacheable(true);
List l=c.list();
Resources resources=(Resources)l.get(0);
System.out.println("-1-"+resources.getName());
HibernateSessionFactory.closeSession();
try ...{
Thread.sleep(5000);
} catch (InterruptedException e) ...{
// TODO Auto-generated catch block
e.printStackTrace();
}
s=HibernateSessionFactory.getSession();
c=s.createCriteria(Resources.class);
c.setCacheable(true);
l=c.list();
resources=(Resources)l.get(0);
System.out.println("-2-"+resources.getName());
HibernateSessionFactory.closeSession();
}
}
?
1. 在Hibernate配置文件中設置:
????

































???
如果不設置“查詢緩存”,那么hibernate只會緩存使用load()方法獲得的單個持久化對象,如果想緩存使用findall()、
list()、Iterator()、createCriteria()、createQuery()等方法獲得的數據結果集的話,就需要設置
hibernate.cache.use_query_cache true 才行
2.首先設置EhCache,建立配置文件ehcache.xml,默認的位置在class-path,可以放到你的src目錄下:





































???????????????????????????????????????????????????????????? Machine.


















??????? " 600 " ?? timeToLiveSeconds = " 600 " ?overflowToDisk = " false " ?diskPersistent = " false " />











以com.ouou.model.Videos為例子
在Videos.hbm.xml中配置:
<class name="Videos" table="TEST" lazy="false">
? <cache usage="read-write" region="ehcache.xml中的name的屬性值"/>注意:這一句需要緊跟在class標簽下面,其他位置無效。
hbm文件查找cache方法名的策略:如果不指定hbm文件中的region="ehcache.xml中的name的屬性值",則使用name名為com.ouou.model.Videos的cache,
如果不存在與類名匹配的cache名稱,則用defaultCache。
如果Videos包含set集合,則需要另行指定其cache
例如Videos包含Tags集合,則需要
添加如下配置到ehcache.xml中
<cache name="com.ouou.model.Tags"
??????? maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="120"
??????? timeToLiveSeconds="120" overflowToDisk="false" />
另,針對查詢緩存的配置如下:
<cache name="org.hibernate.cache.UpdateTimestampsCache"
??????? maxElementsInMemory="5000"
??????? eternal="true"
??????? overflowToDisk="true"/>
<cache name="org.hibernate.cache.StandardQueryCache"
??????? maxElementsInMemory="10000"
??????? eternal="false"
??????? timeToLiveSeconds="120"
??????? overflowToDisk="true"/>
3、 選擇緩存策略依據:
<cache? usage="transactional|read-write|nonstrict-read-write|read-only" (1)/>
ehcache不支持transactional,其他三種可以支持。
read-only:無需修改, 那么就可以對其進行只讀 緩存,注意,在此策略下,如果直接修改數據庫,即使能夠看到前臺顯示效果,
但是將對象修改至cache中會報error,cache不會發生作用。另:刪除記錄會報錯,因為不能在read-only模式的對象從cache中刪除。
read-write:需要更新數據,那么使用讀/寫緩存 比較合適,前提:數據庫不可以為serializable transaction isolation level
(序列化事務隔離級別)
nonstrict-read-write:只偶爾需要更新數據(也就是說,兩個事務同時更新同一記錄的情況很不常見),也不需要十分嚴格的事務隔離,
那么比較適合使用非嚴格讀/寫緩存策略。
4、 調試時候使用log4j的log4j.logger.org.hibernate.cache=debug,更方便看到ehcache的操作過程,主要用于調試過程,實際應用發布時候,請注釋掉,以免影響性能。
5、 使用ehcache,打印sql語句是正常的,因為query cache設置為true將會創建兩個緩存區域:一個用于保存查詢結果集 (
org.hibernate.cache.StandardQueryCache);另一個則用于保存最近查詢的一系列表的時間戳(org.hibernate.cache.UpdateTimestampsCache)。
請注意:在查詢緩存中,它并不緩存結果集中所包含的實體的確切狀態;它只緩存這些實體的標識符屬性的值、以及各值類型的結果。
需要將打印sql語句與最近的cache內容相比較,將不同之處修改到cache中,所以查詢緩存通常會和二級緩存一起使用。
?
Ehcache的配置說明
<ehcache>
<!--
磁盤存儲配置:
用來指定緩存在磁盤上的存儲位置。可以使用JavaVM環境變量(user.home, user.dir, java.io.tmpdir)
-->
<diskStore path = "/var/apps/cache/" />
<!--
指定CacheManagerEventListenerFactory,這個對象在緩存添加的時候會得到相應的通知
CacheManagerEventListenerFactory的屬性
*class - CacheManagerEventListenerFactory的一個實現類
*properties - CacheManagerEventListenerFactory的屬性值,以逗號(,)分割多個屬性
如果沒有實現類被指定,則系統不創建CacheManager的監聽器,沒有默認值
-->
<cacheManagerEventListenerFactory class="" properties="" />
<!--
在進行分布式緩存的應用時候需要指定CacheManagerPeerProviderFactory,
用來生成CacheManagerPeerProvider的實例,以便和集群中的其他CacheManager通信。
*class -CacheManagerPeerProviderFactory的一個實現類
*properties - CacheManagerPeerProviderFactory的屬性值,以逗號(,)分割多個屬性
Ehcache內建了2種基于RMI分布系統的通信策略:
*automatic - 使用多播組。在一個節點加入或者推出集群的時候自動感應
*manual - 硬編碼方式
目前的awf中不考慮分布緩存
-->
<cacheManagerPeerListenerFactory class="" properties="" />
<!--
緩存配置。
以下屬性是必須的:
name - cache的標識符,在一個CacheManager中必須唯一
maxElementsInMemory - 在內存中緩存的element的最大數目
maxElementsOnDisk - 在磁盤上緩存的element的最大數目
eternal - 設定緩存的elements是否有有效期。如果為true,timeouts屬性被忽略
overflowToDisk - 設定當內存緩存溢出的時候是否將過期的element緩存到磁盤上
以下屬性是可選的:
timeToIdleSeconds - 緩存element在過期前的空閑時間。默認為0,表示可空閑無限時間.
??????? (如果指定了這個時間,是否在被hit的前超過了這個時間就會被remove?在內存緩存數目超限之前不會被remove)
timeToLiveSeconds - 緩存element的有效生命期。這個類似于timeouts,默認為0,不過期
??????? (是否通常情況下應該大于等于timeToIdleSeconds,小于會如何?idle時間也會減小和這個數值一樣)
diskPersistent - 在VM重啟的時候是否持久化磁盤緩存,默認是false。
??????? (測試一下true的情況?重載vm的時候會從磁盤進行序列化到對象)
diskExpiryThreadIntervalSeconds - 磁盤緩存的清理線程運行間隔,默認是120秒.
??????? (測試一下0的時候會如何)
memoryStoreEvictionPolicy - 當內存緩存達到最大,有新的element加入的時候,
??????? 移除緩存中element的策略。默認是LRU,可選的有LFU和FIFO
可對緩存中的element配置諸如監聽器和加載器。Ehcahe內建了一些
*cacheEventListenerFactory - 監聽緩存中element的put, remove, update和expire事件
*bootstrapCacheLoaderFactory - 啟動時加載緩存的element
每個用來做分布式緩存都必須設定element的事件監聽器,用來在各個CacheManager節點復制消息。
Ehcache內建了基于RMI的實現 - RMICacheReplicatorFactory
??? <cacheEventListenerFactory class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
??????? properties="replicateAsynchronouly=true,
??????? replicatePuts=true,
??????? replicateUpdates=true,
??????? replicateUpdateViaCopy=true,
??????? replicateRemovals=true" />
-->
<cache .... />
<!--
默認的Cache配置。用來實現CacheManager.add(String cacheName)創建的緩存
-->
<defaultCache maxElementsInMemory="10000" eternal="false"
??????? timeToIdleSeconds="120" timeToLiveSeconds="120"
??????? overflowToDisk="true" maxElementsOnDisk="1000000"
??????? diskPersistent="false" diskExpiryThreadIntervalSeconds="120"
??????? memoryStoreEvictionPolicy="LRU"
??????? />
</ehcache>