Hibernate緩存
緩存是所有關於應用程序的性能優化和它位於應用程序和數據庫之間,以避免數據庫訪問多次,讓性能關鍵型應用程序有更好的表現。
緩存對Hibernate很重要,它采用了多級緩存方案下文所述:
第一級緩存:
第一級緩存是Session的緩存,是一個強製性的緩存,通過它所有的請求都必須通過。 Session對象不斷自身的動力的對象,提交到數據庫之前。
如果發出多個更新一個對象,Hibernate試圖拖延儘可能長的時間做了更新,以減少發出的更新SQL語句的數量。如果您關閉會話,所有被緩存的對象都將丟失,要麼持久,或在數據庫中更新。
二級緩存:
二級緩存是可選的緩存和一級緩存,總是會征詢任何試圖找到一個對象的二級緩存之前。第二級緩存可以在每個類和每個集合基礎上進行配置,主要負責在會話緩存的對象。
任何第三方緩存可以使用Hibernate。org.hibernate.cache.CacheProvider接口提供,必須實施提供Hibernate一個句柄緩存實現。
查詢級彆緩存:
Hibernate也實現了查詢結果集緩存與二級緩存的緊密集成在一起。
這是一個可選功能,需要兩個額外的物理緩存中保存緩存的查詢結果和地區當一個表的最後更新的時間戳。這隻是針對那些使用相同的參數經常運行的查詢非常有用。
二級緩存:
Hibernate使用一級緩存,默認情況下,你什麼都冇有做使用第一級緩存。讓我們直接進入可選的第二級緩存。並不是所有的類受益於緩存,這樣一來就能禁用二級緩存是很重要的
Hibernate二級緩存被設置為兩個步驟。首先,必須決定要使用的並發策略。在此之後,可以配置緩存過期和使用緩存提供物理緩存屬性。
並發策略:
並發策略是一個中介的負責存儲數據項在緩存並從緩存中檢索它們。如果要啟用二級緩存,將必須決定,為每個持久化類和集合,要使用的緩存並發策略。
-
Transactional: 使用這種策略的主要讀取數據的地方,以防止過時的數據的並發事務,在更新的罕見情況下是至關重要的。
-
Read-write: 再次使用這種策略的主要讀取數據的地方,以防止並發事務陳舊的數據是至關重要的,在更新的罕見情況。
-
Nonstrict-read-write: 這種策略不保證緩存與數據庫之間的一致性。使用此策略,如果數據很少改變和陳舊數據的可能性很小關鍵是不關注。
-
Read-only: 並發策略適用於數據,永遠不會改變。使用數據僅供參考。
如果我們要使用第二級緩存為我們的Employee類,讓我們添加告訴Hibernate使用可讀寫的高速緩存策略Employee實例所需的映射元素。
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <class name="Employee" table="EMPLOYEE"> <meta attribute="class-description"> This class contains the employee detail. </meta> <cache usage="read-write"/> <id name="id" type="int" column="id"> <generator class="native"/> </id> <property name="firstName" column="first_name" type="string"/> <property name="lastName" column="last_name" type="string"/> <property name="salary" column="salary" type="int"/> </class> </hibernate-mapping>
usage="read-write" 屬性告訴Hibernate使用一個可讀寫的並發策略定義的緩存。
緩存提供者:
考慮到會用你的緩存候選類的並發策略後,下一步就是選擇一個緩存提供程序。Hibernate迫使選擇一個緩存提供整個應用程序。
S.N. | 緩存名稱 | 描述 |
---|---|---|
1 | EHCache | 它可以在內存或磁盤上以及群集緩存緩存,它支持可選的Hibernate查詢結果緩存。 |
2 | OSCache | 支持緩存內存和磁盤在一個JVM中,有一組豐富的過期策略和查詢緩存的支持。 |
3 | warmCache | 基於JGroups的集群緩存。它使用群集失效,但不支持Hibernate的查詢緩存 |
4 | JBoss Cache | 一個完全的事務複製的集群緩存也是基於JGroups的組播庫。它支持複製或失效,同步或異步通信,樂觀和悲觀鎖定。支持Hibernate的查詢緩存 |
每一個緩存提供程序是不是與每個並發策略兼容。以下兼容性矩陣將幫助選擇合適的組合。
Strategy/Provider | Read-only | Nonstrictread-write | Read-write | Transactional |
---|---|---|---|---|
EHCache | X | X | X | |
OSCache | X | X | X | |
SwarmCache | X | X | ||
JBoss Cache | X | X |
在指定hibernate.cfg.xml配置文件中的緩存提供。選擇EHCache作為第二級緩存提供程序:
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE hibernate-configuration SYSTEM "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <property name="hibernate.dialect"> org.hibernate.dialect.MySQLDialect </property> <property name="hibernate.connection.driver_class"> com.mysql.jdbc.Driver </property> <!-- Assume students is the database name --> <property name="hibernate.connection.url"> jdbc:mysql://localhost/test </property> <property name="hibernate.connection.username"> root </property> <property name="hibernate.connection.password"> root123 </property> <property name="hibernate.cache.provider_class"> org.hibernate.cache.EhCacheProvider </property> <!-- List of XML mapping files --> <mapping resource="Employee.hbm.xml"/> </session-factory> </hibernate-configuration>
現在,需要指定緩存區域的屬性。EHCache都有自己的配置文件ehcache.xml,在應用程序在CLASSPATH中。在ehcache.xml中Employee類高速緩存配置可能看起來像這樣:
<diskStore path="java.io.tmpdir"/> <defaultCache maxElementsInMemory="1000" eternal="false" timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="true" /> <cache name="Employee" maxElementsInMemory="500" eternal="true" timeToIdleSeconds="0" timeToLiveSeconds="0" overflowToDisk="false" />
就這樣,現在啟用Employee類的二級緩存和Hibernate現在二級緩存,每當瀏覽到一個雇員或當通過標識符加載雇員。
應該分析你所有的類,並選擇適當的緩存策略為每個類。有時,二級緩存可能降級的應用程序的性能。所以建議到基準應用程序第一次冇有啟用緩存,非常適合緩存和檢查性能。如果緩存不提高係統性能再有就是在使任何類型的緩存是冇有意義的。
查詢級彆緩存:
使用查詢緩存,必須先使用 hibernate.cache.use_query_cache="true"屬性配置文件中激活它。如果將此屬性設置為true,讓Hibernate的在內存中創建所需的高速緩存來保存查詢和標識符集。
接下來,使用查詢緩存,可以使用Query類的setCacheable(Boolean)方法。例如:
Session session = SessionFactory.openSession(); Query query = session.createQuery("FROM EMPLOYEE"); query.setCacheable(true); List users = query.list(); SessionFactory.closeSession();
Hibernate也支持通過一個緩存區域的概念非常細粒度的緩存支持。緩存區是這是給定一個名稱緩存的一部分。
Session session = SessionFactory.openSession(); Query query = session.createQuery("FROM EMPLOYEE"); query.setCacheable(true); query.setCacheRegion("employee"); List users = query.list(); SessionFactory.closeSession();
此代碼使用方法告訴Hibernate來存儲和查找在緩存中的員工方麵的查詢。