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 SessionFactory -->
< bean id = " sessionFactory " class = " org.springframework.orm.hibernate3.LocalSessionFactoryBean " >
< property name = " dataSource " ref = " dataSource " />
< property name = " mappingResources " >
< list >
< value > com / ouou / model / Videos.hbm.xml </ value >
</ list >
</ property >
< property name = " hibernateProperties " >
< props >
< prop key = " hibernate.dialect " > org.hibernate.dialect.MySQLDialect </ prop >
< prop key = " hibernate.current_session_context_class " > thread </ prop >
< prop key = " hibernate.cglib.use_reflection_optimizer " > false </ prop >
< prop key = " hibernate.query.substitutions " > true ' Y ' , false ' N ' </ prop >
<!-- add ehcache -->
< prop key = " hibernate.cache.provider_class " > org.hibernate.cache.EhCacheProvider </ prop >
< prop key = " hibernate.cache.use_query_cache " > false </ prop ><!-- 是否使用查詢緩存 -->
<!--
< prop key = " hibernate.cache.provider_configuration_file_resource_path " >/ ehcache.xml </ prop >
< prop key = " hibernate.show_sql " > true </ prop >
-->
<!--< prop key = " hibernate.transaction.auto_close_session " > true </ prop >-->
< prop key = " connection.provider_class " > org.hibernate.connection.C3P0ConnectionProvider </ prop >
<!-- Create / update the database tables automatically when the JVM starts up
< prop key = " hibernate.hbm2ddl.auto " > update </ prop > -->
<!-- Turn batching off for better error messages under PostgreSQL -->
< prop key = " hibernate.jdbc.batch_size " > 25 </ prop >
<!--
< prop key = " hibernate.connection.pool_size " > 10 </ prop >
-->
</ props >
</ property >
</ bean >
如果不設置“查詢緩存”,那么hibernate只會緩存使用load()方法獲得的單個持久化對象,如果想緩存使用findall()、 list()、Iterator()、createCriteria()、createQuery()等方法獲得的數據結果集的話,就需要設置 hibernate.cache.use_query_cache true 才行
2.首先設置EhCache,建立配置文件ehcache.xml,默認的位置在class-path,可以放到你的src目錄下:
< ehcache >
<!-- Sets the path to the directory where cache .data files are created.

If the path is a Java System Property it is replaced by
its value in the running VM.
The following properties are translated:
user.home - User ' s home directory
user.dir - User ' s current working directory
java.io.tmpdir - Default temp file path -->
<!--< diskStore path = " java.io.tmpdir " />-->
< diskStore path = " /data/ehcache " />
<!-- Default Cache configuration. These will applied to caches programmatically created through
the CacheManager.

The following attributes are required:

maxElementsInMemory - Sets the maximum number of objects that will be created in memory
eternal - Sets whether elements are eternal. If eternal, timeouts are
ignored and the element is never expired.
overflowToDisk - Sets whether elements can overflow to disk when the in - memory cache
has reached the maxInMemory limit.

The following attributes are optional:
timeToIdleSeconds - Sets the time to idle for an element before it expires.
i.e. The maximum amount of time between accesses before an
element expires Is only used if the element is not eternal.
Optional attribute. A value of 0 means that an Element can idle
for infinity.The default value is 0 .
timeToLiveSeconds - Sets the time to live for an element before it expires.
i.e. The maximum time between creation time and when an element
expires. Is only used if the element is not eternal.
Optional attribute. A value of 0 means that and Element can live
for infinity.
The default value is 0 .
diskPersistent - Whether the disk store persists between restarts of the Virtual
Machine.
The default value is false .
diskExpiryThreadIntervalSeconds - The number of seconds between runs of the disk expiry thread.
The default value is 120 seconds.
-->
< defaultCache
maxElementsInMemory = " 10000 "
eternal = " false "
overflowToDisk = " true "
timeToIdleSeconds = " 120 "
timeToLiveSeconds = " 120 "
diskPersistent = " false "
diskExpiryThreadIntervalSeconds = " 120 " />
< cache name = " org.hibernate.cache.UpdateTimestampsCache " maxElementsInMemory = " 5000 "
eternal = " true " overflowToDisk = " true " />
< cache name = " org.hibernate.cache.StandardQueryCache " maxElementsInMemory = " 5 " eternal = " false "
timeToLiveSeconds = " 120 " overflowToDisk = " true " />
< cache name = " userCache " maxElementsInMemory = " 100000 " eternal = " false " timeToIdleSeconds =
" 600 " timeToLiveSeconds = " 600 " overflowToDisk = " false " diskPersistent = " false " />
< cache name = " com.ouou.webapp.util.OuouMethodIntecepter " maxElementsInMemory = " 100000 "
eternal = " false " timeToIdleSeconds = " 600 " timeToLiveSeconds = " 600 " overflowToDisk = " false "
diskPersistent = " false " />
< cache name = " bbcode " maxElementsInMemory = " 100000 " eternal = " false " timeToIdleSeconds = " 600 "
timeToLiveSeconds = " 600 "
overflowToDisk = " false " diskPersistent = " false " />
< cache name = " com.ouou.model.Videos " maxElementsInMemory = " 10000 " eternal = " false "
overflowToDisk = " false " timeToIdleSeconds = " 120 " timeToLiveSeconds = " 120 " diskPersistent = " false " />
< cache name = " com.ouou.model.Tags " maxElementsInMemory = " 10000 " eternal = " false "
overflowToDisk = " false " timeToIdleSeconds = " 120 " timeToLiveSeconds = " 120 " diskPersistent = " false " />
</ ehcache >
以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>