Hibernate緩存概述
1、Hibernate緩存概述
緩存是介于物理數據源與應用程序之間,是數據庫數據在內存中的存放臨時copy的容器,其作用是為了減少應用程序對物理數據源訪問的次數,從而提高了應用的運行性能。
Hibernate在進行讀取數據的時候,根據緩存機制在相應的緩存中查詢,如果在緩存中找到了需要的數據(我們把這稱做“緩存命中"),則就直接把命中的數據作為結果加以利用,避免了建立數據庫查詢的性能損耗。
2:Hibernate緩存分類
一級緩存(session):內部緩存
事務范圍:緩存只能被當前事務訪問。緩存的生命周期依賴于事務的生命周期,當事務結束時,緩存也就結束生命周期。
二級緩存(sessionFactory):緩存被應用范圍內的所有事務共享。
這些事務有可能是并發訪問緩存,因此必須對緩存進行更新。
緩存的生命周期依賴于應用的生命周期,應用結束時,緩存也就結束了生命周期,二級緩存存在于應用范圍。
集群范圍:在集群環境中,緩存被一個機器或者多個機器的進程共享。
緩存中的數據被復制到集群環境中的每個進程節點,進程間通過遠程通信來保證緩存中的數據的一致性,緩存中的數據通常采用對象的松散數據形式,二級緩存也存在與應用范圍。
注意:對大多數應用來說,應該慎重地考慮是否需要使用集群范圍的緩存,再加上集群范圍還有數據同步的問題,所以應當慎用。
多種范圍的緩存處理過程
持久化層可以提供多種范圍的緩存。如果在事務范圍的緩存中沒有查到相應的數據,
還可以到應用范圍或集群范圍的緩存內查詢,如果還是沒有查到,那么只有到數據庫中查詢了。
緩存應用的范圍:
修改少,數量在可以接受的范圍內
使用二級緩存的原則:
數據不會被第三方修改
同一數據系統經常引用
數據大小在可接受范圍之內
關鍵數據或不會被并發更新的數據
hibernate引入第三方的緩存組件EHCACHE,下面是具體的實現步驟:
修改hibernate.cfg.xml配置引入ehCache緩存
- < hibernate-configuration>
- < session-factory>
- < property name="hibernate.cache.provider_class">
- net.sf.ehcache.hibernate.EhCacheProvider
- < /property>
- < !--query也支持緩存-->
- < property name="hibernate.cache.use_query_cache">true< /property>
- < /session-factory>
- < /hibernate-configuration>
在src根目錄下加入ehcache.xml文件,具體內容如下:
- < ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="ehcache.xsd">
- < defaultCache
- maxElementsInMemory="10000"
- eternal="false"
- timeToIdleSeconds="120"
- timeToLiveSeconds="120"
- overflowToDisk="true"
- />
- < /ehcache>
在映射文件中指定緩存同步策略
- < class name="com.tenly.bean.Student">
- < cache usage="read-write">
- < set name="classroom">
- < cache usage="read-only">
- < /set>
- < /class>
usage屬性說明:
read-only:只讀。對于不會發生改變的數據,可使用只讀型緩存。
nonstrict-read-write:不嚴格可讀寫緩存。如果應用程序對并發訪問下的數據同步要求不是很嚴格的話,
而且數據更新操作頻率較低。采用本項,可獲得良好的性能。
read-write
對于經常被讀但很少修改的數據,可以采用這種隔離類型,因為它可以防止臟讀這類的并發問題.
transactional(事物型)
在Hibernate中,事務型緩存必須運行在JTA事務環境中。
在測試query時,說明其將用二級緩存
query.setCacheable(true);
釋放Hibernate緩存:
一級緩存的釋放
Session.evict(XXX)
將某個特定的對象從內部緩存中清除,上述的XXX 為對象的實例名。使用此方法有兩種適用情形,
需要及時釋放對象占用的內存維持系統的穩定性
是不希望當前Session繼續運用此對象的狀態變化來同步更新數據庫。
Session.clear()清除所有的一級緩存
二級緩存的釋放
SessionFacatoyr.evict(XXX)
將某個特定的對象從內部緩存中清除,上述的XXX 為對象的實例名。使用此方法有兩種適用情形,
需要及時釋放對象占用的內存維持系統的穩定性
是不希望當前Session繼續運用此對象的狀態變化來同步更新數據庫。
SessionFactory.clear()清除所有的二級緩存
查詢緩存:
二級緩存策略的一般過程:
Hibernate進行條件查詢的時候,總是發出一條select * from XXX where …(XXX為 表名,
類似的語句下文統稱Select SQL)這樣的SQL語句查詢數據庫,一次獲得所有的符合條件的數據對象。
把獲得的所有數據對象根據ID放入到第二級緩存中。
當Hibernate根據ID訪問數據對象的時候,首先從內部緩存中查找,如果在內部緩存中查不到就配置二級緩存,
從二級緩存中查;如果還查不到,再查詢數據庫,把結果按照ID放入到緩存。
添加數據、刪除、更新操作時,同時更新二級緩存。這就是Hibernate做批處理的時候效率不高的原因,
原來是要維護二級緩存消耗大量時間的緣故。
條件查詢的處理過程:
***次查找age>20的所有學生信息,然后納入二級緩存。
第二次我們的查詢條件變了,查找age>15的所有學生信息,顯然***次查詢的結果完全滿足第二次查詢的條件,
但并不是滿足條件的全部數據。這樣的話,我們就要再做一次查詢得到全部數據才行。
如果我們執行的是相同的條件語句,Hibernate引入Query Cache的。
查詢緩存策略的一般過程:
完全相同的Select SQL重復執行。
重復執行期間,Query Key對應的數據表不能有數據變動(比如添、刪、改操作)
啟用Query Cache,我們需要在hibernate.cfg.xml中進行配置,參考配置如下(只列出核心配置項):
- < hibernate-configuration>
- < session-factory>
- < property name="hibernate.cache.user_query_cache">true< /property>
- < /session-factory>
- < /hibernate-configuration>
在查詢執行之前,將Query.Cacheable設置為true,而且每次都應該這樣。比如:
Query query=session.createQuery(hql).setInteger(0.15);
query.setCacheable(true);
【編輯推薦】