Terry.Li-彬

          虛其心,可解天下之問;專其心,可治天下之學;靜其心,可悟天下之理;恒其心,可成天下之業。

            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
            143 隨筆 :: 344 文章 :: 130 評論 :: 0 Trackbacks

          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?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>

          posted on 2010-08-08 16:40 禮物 閱讀(3913) 評論(0)  編輯  收藏 所屬分類: cache
          主站蜘蛛池模板: 银川市| 武强县| 连平县| 江城| 尉犁县| 古田县| 台北县| 缙云县| 甘洛县| 泰兴市| 磐安县| 营山县| 宜良县| 旬邑县| 玛沁县| 巴青县| 金塔县| 津市市| 论坛| 玉溪市| 九江县| 隆尧县| 清河县| 洛川县| 汝州市| 常州市| 隆林| 德格县| 饶阳县| 烟台市| 香港| 赤峰市| 禹城市| 化隆| 炎陵县| 银川市| 定兴县| 信丰县| 洪江市| 富蕴县| 时尚|