Hibernate緩存:緩存是在內存中的一塊高速區域。
Hibernate緩存的作用:可以把查詢出來的數據存儲在內存或者磁盤,節省下次同樣查詢語句再次查詢數據庫,大幅減輕數據庫壓力。
在Hibernate中,緩存分爲2種方式:
1.一級緩存: Hibernate默認支持的,是屬於Session級別的,也就是說跟它跟Session的生命週期息息相關。
2.二級緩存:Hibernate二級緩存是一個可插拔的的緩存插件,它是由SessionFactory負責管理。由於SessionFactory對象的生命週期和應用程序的整個過程對應。
Hibernate的二級緩存策略的一般過程如下:
1.配置好二級緩存。
2.如:執行get(User.class,1);然後關閉session,這個時候,同樣在執行一次get(User.class,1);這樣的語句,它在執行第一次的時候,首先,先將第一次查詢到的結果放到一級緩存中,並複製一份放到二級緩存中,然後把id爲1作爲key放入一個內存中的id列表裏面,當第二次執行同樣的代碼的時候,會先在一級緩存裏找,這個時候因爲Session已經關閉了,那麼就會到二級緩存裏面找,先找在id列表裏面找id爲1的的id列表,很顯然會找到,然後會根據這個id在相應的類緩存中找到對應的對象。
在二級緩存中還有一個查詢緩存,它只對list起作用,對iterator不起作用。
Hibernate查詢緩存 生命週期不固定 ,當數據庫 表發生改變的使用Hibernate查詢緩存馬上消失。
Hibernate的查詢緩存策略的過程如下:
1.啓動查詢緩存。
2.然後執行如:session.createQuery("fromUser where id=1").setCacheable(true).list();setCacheable(true)激活查詢緩存,然後在Session關閉以後,在執行一條session.createQuery("fromUser where id=1").setCacheable(true).list();這樣的語句,第一次執行的時候,會先將第一次查詢到的結果放入到一級緩存中,並將該實體的id爲key放入到二級緩存中,然後以SQL爲key放入的二級緩存的查詢緩存中,當第二次執行相同的語句的時候,系統會先在一級緩存中裏面找,如果找不到,在到二級緩存中來找,系統會先根據id爲因爲是HQL語句來查詢的所以沒有id項,然後就會根據SQL來到二級緩存中的查詢緩存裏面來找,這次找到了,就返回該實體。
好了,說了那麼多,接下來我們來實戰一下:
首先是先在Hibernate-cfg.xml裏面來配置二級緩存,配置如下:
1. <!-- 啓動二級緩存 -->
2. <!-- 打開二級緩存 -->
3. <property name="cache.use_second_level_cache">true</property>
4. <!-- 設置Hibernate的緩存接口類,也就是選用緩存的組件 -->
5. <property name="cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
6. <!-- 啓動查詢緩存 -->
7. <property name="cache.use_query_cache">true</property>
8. <mapping resource="com/lovo/po/User.hbm.xml"/>
9. <!-- 要緩存的類 -->
10. <class-cache class="com.lovo.po.User" usage="read-write"/>
這裏,我們主要來說下usage的配置項有:
只讀緩存(read-only)
如果應用程序需要讀取一個持久化類的實例,但是並不打算修改它們,可以使用read-only緩存。這是最簡單,也是實用性最好的策略。
對於從來不會修改的數據,如參考數據,可以使用這種併發訪問策略。
讀/寫緩存(read-write)
如果應用程序需要更新數據,可能read-write緩存比較合適。如果需要序列化事務隔離級別,那麼就不能使用這種緩存策略。
對於經常被讀但很少修改的數據,可以採用這種隔離類型,因爲它可以防止髒讀這類的併發問題。
不嚴格的讀/寫緩存(nonstrict-read-write)
如果程序偶爾需要更新數據(也就是說,出現兩個事務同時更新同一個條目的現象很不常見),也不需要十分嚴格的事務隔離,可能適用nonstrict-read-write緩存。
對於極少被修改,並且允許偶爾髒讀的數據,可以採用這種併發訪問策略。
事務緩存(transactional)
transactional緩存策略提供了對全事務的緩存,僅僅在受管理環境中使用。它提供了Repeatable Read事務隔離級別。對於經常被讀但很少修改的數據,可以採用這種隔離類型,因爲它可以防止髒讀和不可重複讀這類的併發問題。
在上面所介紹的隔離級別中,事務型併發訪問策略的隔離級別最高,然後依次是讀/寫型和不嚴格讀寫型,只讀型的隔離級別最低。事務的隔離級別越高,併發性能就越低。
接着,就是在src目錄下面加入ehcache.xml這個文件,這個文件可以在Hibernate源碼包中找到,具體配置如下:
1. <diskStore path="D:/Java/temp"/><!-- 如果超出記錄數量,將序列化到硬盤上,默認的是java.io.tmpdir -->
2. <!--緩存可以存儲的總記錄量-->
3. <!--緩存是否永遠不銷燬-->
4. <!--當緩存閒置時間超過該值,則緩存自動銷燬-->
5. <!--緩存創建之後,到達該緩存自動銷燬-->
6. <!--當緩存中的數據達到最大值時,是否把緩存數據寫入磁盤-->
7. <defaultCache
8. maxElementsInMemory="1"
9. eternal="false"
10. timeToIdleSeconds="1200"
11. timeToLiveSeconds="1200"
12. overflowToDisk="true"
13. />