Hibernate提供了三個級別的緩存策略:Session緩存(基本的事務級緩存),Query Cache(查詢緩存),Seond-Level Cache(二級緩存)
Session緩存(First-Level Cache):Session是Hibernate用于管理持久化對象的核心機制,它是針對持久性數據的事務級緩存。PersistenceContext中包括:
entityKeys,collectionKeys,
insertion,updates,deletions,
collectionCreations,collectionRemovals,collectionUpdates
由此可見,Session不會把所有的持久化對象實體本身緩存,而只是緩存實體或Collection的Identiy值,和狀態被更新過的實體或Collection(包括插入,更新,刪除)
當Session中緩存的內容過多時會導致OutOfMemory的問題,可以通過兩種方式刪除緩存的內容:
- clear(): 清除所有Session緩存;
- evict(PersistentObject): 將一個特定持久化對象從Session緩存中刪除。
Query Cache:Hibernate可以對頻繁進行的查詢(相同查詢,相同參數)進行緩存以提高效率。但是查詢緩存不會緩存結果集中實際的數據實體,而是只緩存Identiy值和結果值類型,因此它應該總是和二級緩存一起使用。但由于實際環境中完全相同的頻繁查詢很少,所以默認該緩存是disabled的。可以通過兩種方式使之生效:(個人覺得這個緩存意義不大)
配置屬性:<prop key="hibernate.cache.use_query_cache">true</prop>
代碼:Query.setCacheable(true)
Second-Level Cache: 二級緩存,用于對持久化對象實體或Collection的實際數據進行緩存,用于提供一個集群級別(cluster level),JVM級別,或文件系統級的緩存機制。Hibernate的二級緩存通常都是由第三方的開源項目提供,可以通過配置選擇特定的緩存實現,例如:EHCache,OSCache,JBoss Cable等。
配置屬性:<prop key="hibernate.cache.provider_class">org.hibernate.cache.OSCacheProvider</prop>
二級緩存同樣可以通過兩種方式來管理:
配置屬性:<prop key="hibernate.cache.use_second_level_cache">false</prop>
代碼:Query.setCacheMode(CacheMode.IGNORE) (或者GET,NORMAL,PUT,REFRESH)
- IGNORE: 禁用二級緩存
- NORMAL: 啟用二級緩存,正常讀寫
- GET: 只從二級緩存讀,除非有數據update
- PUT: 只向二級緩存寫
- REFRESH: 強制對寫入二級緩存的內容進行刷新
最后,在程序調試中,我們可能需要查看各種Cache中實際緩存的內容,可以通過配置屬性讓Hibernate收集緩存統計信息。當我們遭遇可能由于緩存導致的問題時,這一方法特別有用。
配置屬性:<prop key="hibernate.generate_statistics">true</prop>
在代碼中獲得統計信息:sessionFactory.getStatistics()