Hibernate的二級緩存攻略

1.聲明:該文章轉帖於:http://www.iteye.com/topic/18904

 

 

2.Class的緩存

   對於一條記錄,也就是一個PO(Persient Object)來說,是根據ID來查找的,緩存的Key就是ID,value就是POJO。無論list,load還是iterate,只要讀出一個對象,都會填充緩存。但是list不會使用緩存,而iterate會先取數據庫的select id出來,然後一個id一個id地load,如果在緩存裏面有,就從緩存取,沒有的話就去數據庫load。假設是讀寫,則需要設置:

<cache usage="read-write"/>(這是是在*.hmb.xml中設置,位於id屬性之前,class屬性之後)

 

同時需要ehcache.xml(放置到classpath目錄下)

<cache name="com.skywin.simpass.db.domain.PartnerInfo"
            maxElementsInMemory="10000"

            eternal="false"

            timeToIdleSeconds="120"
            timeToLiveSeconds="360"

            overflowToDisk="false" />

 

其中:

     eternal表示的是:緩存是不是永遠不過期。(關於過期時間的判斷是由  org.hibernate.cache.UpdateTimestampsCache時間戳決定的)

 

     timeToLiveSeconds表示的是:緩存中每個元素(這裏也就是一個POJO)的超時時間,如果eternal設定是false的話,超過指定的時間,這個元素就被移走。

 

     timeToIdleSeconds指的是:空閒時間(暫時沒有搞定這個東西)

 

每個需要緩存的class都要這樣配置。如果沒有配置,hibernate會在啓動時警告你,然後使用defaultCache的配置,這樣多個class會共享一個配置。

     (關於Hibernate的ehcach.xml二級緩存配置,詳見附件)

 

      當某個ID通過Hibernate修改時,Hibernate會知道,於是先移除緩存。

 

 

3.查詢緩存

   首先要配置:hibernate.cache.use_query_cache=true(在hibernate.cfg.xml或者spring的applicationContext.xml的bean id="sessionFactory"中爲其聲明)。

 

   其次配置StandardQueryCache

   <cache name="org.hibernate.cache.StandardQueryCache"
        maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="120"
        timeToLiveSeconds="360" overflowToDisk="false" />

 

   然後使用Query接口的setCacheable(true);//激活查詢緩存

   query.setCacheRegion("myCacheRegion"); //指定要使用的cacheRegion,options

 

  ( 哈哈,一般我都不習慣使用這個東西)

  <cache name="myCacheRegion"
        maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="120"
        timeToLiveSeconds="360" overflowToDisk="false" />

 

   對於查詢緩存來說,緩存Key是根據hql生成的sql,再加上參數,分頁等信息。

   比如hql:

   from Cat c where c.name like ? (Query接口默認的是select 操作)

 

   生成的sql語句大致如下:

   select * from cat c where c.name like ?

   參數是"tiger%",那麼查詢緩存的key大致會組裝成這樣子的:

   select * from cat c where c.name like ?, parameter: tiger%

 

   這樣,保證了同樣的查詢,同樣的參數等條件下具有一樣的key。

 

   現在說說緩存的value,如果是list方式的話,Value在這裏並不是整個結果集,而是查詢出來的這一串ID。也就是說,不管是list方法還是iterate方法,第一次查詢的時候,它們的查詢方式和它們平時的方式是一樣的,list執行一條sql,iterate執行1+N條,多出來的行爲是它們填充了緩存。

 

當hibernate更新數據庫的時候,它怎麼知道更新哪些查詢緩存呢?
hibernate在一個地方維護每個表的最後更新時間,其實也就是放在上面org.hibernate.cache.UpdateTimestampsCache(Hibernate 2.0版本是net.sf)所指定的緩存配置裏面。
當通過hibernate更新的時候,hibernate會知道這次更新影響了哪些表。然後它更新這些表的最後更新時間。每個緩存都有一個生成時 間和這個緩存所查詢的表,當hibernate查詢一個緩存是否存在的時候,如果緩存存在,它還要取出緩存的生成時間和這個緩存所查詢的表,然後去查找這 些表的最後更新時間,如果有一個表在生成時間後更新過了,那麼這個緩存是無效的。
可以看出,只要更新過一個表,那麼凡是涉及到這個表的查詢緩存就失效了,因此查詢緩存的命中率可能會比較低。

 

 

4.Collection緩存

   需要在*.hbm.xml的collection(set/bag/...)裏面設置

   <cache usage="read-write"/>

 

 

   同時,需要在ehcache.xml中增加

   <cache name="...Cat.children"

               .../>

 

   Collection的緩存和前面查詢緩存的list一樣,也是隻保持一串id,但是它不會因爲這個表更新過就失效,一個collection緩存僅在這個collection裏面的元素有增刪時才失效。

 

 

 

 

 

 

 

 

 

 

發佈了38 篇原創文章 · 獲贊 0 · 訪問量 1746
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章