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裏面的元素有增刪時才失效。