具體解釋Hibernate中的二級緩存
1.前言
這篇博客再前幾篇博客的基礎上來解說一下。Hibernate中的二級緩存。二級緩存是屬於SessionFactory級別的緩存機制。
第一級別的緩存是Session級別的緩存,是屬於事務範圍的緩存,由Hibernate管理,一般無需進行幹預。第二級別的緩存是SessionFactory級別的緩存。是屬於進程範圍的緩存。
2.Hibernate二級緩存
1.分類
二級緩存也分為了兩種
內置緩存:Hibernate自帶的,不可卸載,通常在Hibernate的初始化階段,Hibernate會把映射元數據和提前定義的SQL語句放置到SessionFactory的緩存中。該內置緩存是僅僅讀的。
外置緩存:通常說的二級緩存也就是外置緩存,在默認情況下SessionFactory不會啟用這個緩存插件,外置緩存中的數據是數據庫數據的復制,外置緩存的物理介質能夠是內存或者硬盤。
hibernate二級緩存的結構
2.並發訪問策略
transactional
(事務型)
僅在受管理的環境中適用
提供Repeatable Read事務隔離級別
適用常常被讀。非常少改動的數據
能夠防止臟讀和不可反復讀的並發問題
緩存支持事務,發生異常的時候。緩存也可以回滾
read-write
(讀寫型)
提供Read Committed事務隔離級別
在非集群的環境中適用
適用常常被讀,非常少改動的數據
能夠防止臟讀
更新緩存的時候會鎖定緩存中的數據
nonstrict-read-write
(非嚴格讀寫型)
適用極少被改動,偶爾同意臟讀的數據(兩個事務同一時候改動數據的情況非常少見)
不保證緩存和數據庫中數據的一致性
為緩存數據設置非常短的過期時間,從而盡量避免臟讀
不鎖定緩存中的數據
read-only
(僅僅讀型)
適用從來不會被改動的數據(如參考數據)
在此模式下,假設對數據進行更新操作,會有異常
事務隔離級別低,並發性能高
在集群環境中也能完美運作
分析:通過上述表格分析例如以下
適合放入二級緩存中數據
非常少被改動
不是非常重要的數據。同意出現偶爾的並發問題
不適合放入二級緩存中的數據
常常被改動
財務數據,絕對不同意出現並發問題
與其它應用數據共享的數據
3.二級緩存的配置
1.hibernate支持的緩存插件
?EHCache: 可作為進程範圍內的緩存,存放數據的物理介質能夠是內存或硬盤,對Hibernate的查詢緩存提供了支持
?OpenSymphony`:可作為進程範圍內的緩存,存放數據的物理介質能夠是內存或硬盤,提供了豐富的緩存數據過期策略,對Hibernate的查詢緩存提供了支持
?SwarmCache:可作為集群範圍內的緩存,但不支持Hibernate的查詢緩存
?JBossCache:可作為集群範圍內的緩存,支持Hibernate的查詢緩存
四種緩存插件支持的並發範圍策略例如以下圖
2.二級緩存配置
以下以ehcache緩存為例,來講一下二級緩存的配置
2.1 拷貝jar包
如要第三方的jar包ehcache-1.5.0.jar,而且依賴於
依賴backport-util-concurrent 和 commons-logging
2.2 在hibernate.cfg.xml中開啟二級緩存
<propertyname="hibernate.cache.use_second_level_cache">true</property>
2.3 配置二級緩存技術提供商
<propertyname="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
2.4 配置緩存數據對象並發策略
方式一 在hbm文件裏配置
<span style="font-family:SimSun;font-size:18px;"><class name="cn.itcast.domain.Customer" table="customers" catalog="hibernate3day4" > <!-- 類級別緩存 --> <cache usage="read-write"/> <set name="orders" cascade="all-delete-orphan" inverse="true" > <!-- 關聯集合級別緩存 --> <cache usage="read-write"/> </set> </class> </span>
方式二 在cfg文件配置(集中配置)
<span style="font-family:SimSun;font-size:18px;"><!-- 類級別緩存 --> <class-cache usage="read-write" class="cn.itcast.domain.Customer"/> <class-cache usage="read-write" class="cn.itcast.domain.Order"/> <!-- 集合緩存 --> <collection-cache usage="read-write" collection="cn.itcast.domain.Customer.orders"/> </span>
2.5 加入二級緩存配置文件
在src中配置ehcache.xml,將ehcache.jar包中的ehcache-failsafe.xml 改名 ehcache.xml 放入 src
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../config/ehcache.xsd"> <diskStore path="java.io.tmpdir"/> 配置二級緩存硬盤暫時文件夾位置 <defaultCache maxElementsInMemory="10000" // 內存中最大對象數量 ,超過數量。數據會被緩存到硬盤 eternal="false" timeToIdleSeconds="120" // 是否緩存為永久性 false 不永久 timeToLiveSeconds="120" // 存活時間。對象無論是否使用,到了時間回收 overflowToDisk="true" // 能否夠緩存到硬盤 maxElementsOnDisk="10000000" // 硬盤緩存最大對象數量 // 當jvm結束時是否持久化對象 true false 默認是false diskExpiryThreadIntervalSeconds="120" // 指定專門用於清除過期對象的監聽線程的輪詢時間 memoryStoreEvictionPolicy="LRU" /> </ehcache>
4.Demo測試二級緩存
@Test public void fun1() { Session s1 = HibernateUtils.getSession(); s1.beginTransaction(); Customer c1 = (Customer) s1.get(Customer.class, 1); // 從數據庫中載入數據 System.out.println(c1.getName());//此時才會發出SQL語句 s1.getTransaction().commit(); s1.close(); // 關閉session級別的一級緩存 Session s2 = HibernateUtils.getSession(); s2.beginTransaction(); Customer c2 = (Customer) s2.get(Customer.class, 1); // 由於有了二級緩存的存在,直接從二級緩存中取出就可以 System.out.println(c2.getName()); Customer c3 = (Customer) s2.get(Customer.class, 1); //從二級緩存中取出 System.out.println(c3.getName()); s2.getTransaction().commit(); s2.close(); }
具體解釋Hibernate中的二級緩存