1. 程式人生 > >具體解釋Hibernate中的二級緩存

具體解釋Hibernate中的二級緩存

store cells ble 發生 結構 查詢 delet esc ren

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中的二級緩存