一級緩存
Hibernate的一級緩存是由Session提供的,因此它只存在于Session的生命周期中,當(dāng)程序調(diào)用save(),update(),saveorupdate()等方法 及調(diào)用查詢接口list,filter,iterate時,如session緩存中還不存在相應(yīng)的對象,Hibernate會把該對象加入到一級緩存中, 當(dāng)Session關(guān)閉的時候該Session所管理的一級緩存也會立即被清除 Hibernate的一級緩存是Session所內(nèi)置的,不能被卸載,也不能進(jìn)行任何配置 二級緩存配置: 1、首先要打開二級緩存,在hibernate.cfg.xml中添加如下配置: <property name="hibernate.cache.use_second_level_cache">true</property> 2、Hibernate的二級緩存使用第三方的緩存工具來實現(xiàn),所以我們需要指定Hibernate使用哪個 緩存工具。如下配置指定Hibernate使用EhCache緩存工具。 <property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property> 3、Hibernate在默認(rèn)情況下并不會對所有實體對象進(jìn)行緩存,所以,我們需要指定緩存哪些對象, 在實體對象的映射文件中(相應(yīng)的<class>標(biāo)簽內(nèi)部),添加如下配置: <cache usage="read-only"/> usage="read-only"是“只讀”緩存策略。 注意,這個<cache>標(biāo)簽只能放在<class>標(biāo)簽的內(nèi)部,而且必須處在<id>標(biāo)簽的前面?。?! 這個<cache>標(biāo)簽放在哪些<class>標(biāo)簽下面,就說明會多這些類的對象進(jìn)行緩存 4、對于第3步,有一個可選的方案是在hibernate.cfg.xml文件中指定哪些類的對象需要緩存, 而不需要使用<cache>標(biāo)簽來指定。如: 在hibernate.cfg.xml中添加如下配置: <class-cache class="com.bjsxt.hibernate.Classes" usage="read-only" /> 注意,這個<class-cache>標(biāo)簽必須放在<mapping>標(biāo)簽的后面!! Hibernate緩存配置 _____________________________________________________________________________________ Hibernate的緩存分為: 一級緩存:在Session級別的,在Session關(guān)閉的時候,一級緩存就失效了。 二級緩存:在SessionFactory級別的,它可以使用不同的緩存實現(xiàn),如EhCache、JBossCache、OsCache等。 緩存的注釋寫法如下,加在Entity的java類上: @Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE) 緩存的方式有四種,分別為: CacheConcurrencyStrategy.NONE CacheConcurrencyStrategy.READ_ONLY,只讀模式,在此模式下,如果對數(shù)據(jù)進(jìn)行更新操作,會有異常; CacheConcurrencyStrategy.READ_WRITE,讀寫模式在更新緩存的時候會把緩存里面的數(shù)據(jù)換成一個鎖,其它事務(wù)如果去取相應(yīng)的緩存數(shù)據(jù),發(fā)現(xiàn)被鎖了,直接就去數(shù)據(jù)庫查詢; CacheConcurrencyStrategy.NONSTRICT_READ_WRITE,不嚴(yán)格的讀寫模式則不會的緩存數(shù)據(jù)加鎖; CacheConcurrencyStrategy.TRANSACTIONAL,事務(wù)模式指緩存支持事務(wù),當(dāng)事務(wù)回滾時,緩存也能回滾,只支持JTA環(huán)境。 另外還有如下注意事項: 1、查詢緩存需要在Query的相應(yīng)方法執(zhí)行前加上這么一句: query.setCacheable(true); 在使用Hibernate時,獲得的query有setCacheable方法,可以設(shè)置使用緩存,但當(dāng)使用JPA時,javax.persistence.Query并沒有setCacheable方法,此時如果JPA的實現(xiàn)是Hibernate時,可以將其進(jìn)行如下轉(zhuǎn)化,再調(diào)用setCacheable方法(如果JPA的實現(xiàn)是其它ORMAP框架,就不知道怎么做了)。 if (query instanceof org.hibernate.ejb.QueryImpl) { ((org.hibernate.ejb.QueryImpl) query).getHibernateQuery().setCacheable(true); } 2、還有就是查詢緩存的查詢執(zhí)行后,會將查詢結(jié)果放入二級緩存中,但是放入的形式是以ID為Key,實例作為一個Value。 3、hibernate的配置文件中需加入如下信息: <property name="hibernate.cache.provider_class" value="org.hibernate.cache.EhCacheProvider" /> <property name="hibernate.cache.use_second_level_cache" value="true" /> <property name="hibernate.cache.use_query_cache" value="true" /> 緩存映射(Cache mappings)
類或者集合映射的“<cache>元素”可以有下列形式:
<cache usage="transactional|read-write|nonstrict-read-write|read-only" (1)/>
(1) usage說明了緩存的策略: transactional、 read-write、 nonstrict-read-write或 read-only。 另外(首選?), 你可以在hibernate.cfg.xml中指定<class-cache>和 <collection-cache> 元素。
這里的usage 屬性指明了緩存并 發(fā)策略(cache concurrency strategy)。 只讀 緩存(read only) 如果你的應(yīng)用程序只需讀取一個持久化類的實例,而無需對其修改, 那么就可以對其進(jìn)行只讀 緩存。這是最簡單,也是實用性最好的方法。甚至在集群中,它也能完美地運作。
<class name="eg.Immutable" mutable="false"> <cache usage="read-only"/> ....</class> 讀/寫緩存( read/write) 如果應(yīng)用程序需要更新數(shù)據(jù),那么使用讀/寫緩存 比較合適。 如果應(yīng)用程序要求“序列化事務(wù)”的隔離級別(serializable transaction isolation level),那么就決不能使用這種緩存策略。 如果在JTA環(huán)境中使用緩存,你必須指定hibernate.transaction.manager_lookup_class屬 性的值, 通過它,Hibernate才能知道該應(yīng)用程序中JTA的TransactionManager的 具體策略。 在其它環(huán)境中,你必須保證在Session.close()、或Session.disconnect()調(diào)用前, 整個事務(wù)已經(jīng)結(jié)束。 如果你想在集群環(huán)境中使用此策略,你必須保證底層的緩存實現(xiàn)支持鎖定(locking)。Hibernate內(nèi)置的緩存策略并不支持鎖定功能。
<class name="eg.Cat" .... > <cache usage="read-write"/> .... <set name="kittens" ... > <cache usage="read-write"/> .... </set></class> 非嚴(yán)格讀/寫緩存(nonstrict read/write) 如果應(yīng)用程序只偶爾需要更新數(shù)據(jù)(也就是說,兩個事務(wù)同時更新同一記錄的情況很不常見),也不需要十分嚴(yán)格的事務(wù)隔離, 那么比較適合使用非嚴(yán)格讀/寫緩存策略。如果在JTA環(huán)境中使用該策略, 你必須為其指定hibernate.transaction.manager_lookup_class屬性的值, 在其它環(huán)境中,你必須保證在Session.close()、或Session.disconnect()調(diào)用前, 整個事務(wù)已經(jīng)結(jié)束
-------------------------------------------------------------------------
在jBPM 中使用不少這樣的非嚴(yán)格讀/寫緩存的處理: <?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate./hibernate-mapping-3.0.dtd"> <hibernate-mapping default-access="field"> <class name="org.jbpm.context.def.VariableAccess" table="JBPM_VARIABLEACCESS" lazy="false"> <cache usage="nonstrict-read-write"/> <id name="id" column="ID_"><generator class="native" /></id> <property name="variableName" column="VARIABLENAME_" /> <property name="access" column="ACCESS_" /> <property name="mappedName" column="MAPPEDNAME_" /> </class> </hibernate-mapping> 它的ehcache.xml 是這樣配置的:
<ehcache> <defaultCache maxElementsInMemory="100000" eternal="true" overflowToDisk="false" diskPersistent="false" /> </ehcache> Hibernate Annotation 中配置EhCache緩存 1. 首先設(shè)置EhCache,建立配置文件ehcache.xml,默認(rèn)的位置在class-path,可以放到你的src目錄下: 1.xml version="1.0" encoding="UTF-8"?>
2.<ehcache> 3. <diskStore path="java.io.tmpdir"/> 4. <defaultCache 5. maxElementsInMemory="10000" 6. eternal="false" 7. 8. overflowToDisk="true" 9. 10. timeToIdleSeconds="300" 11. timeToLiveSeconds="180" 12. diskPersistent="false" 13. diskExpiryThreadIntervalSeconds= "120"/> 14.ehcache> 2. 在Hibernate配置文件中設(shè)置:
<hibernate-configuration><session-factory>……<property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property><property name="cache.use_second_level_cache">true</property>……</session-factory></hibernate-configuration>
此外,可以把cache.use_second_level_cache設(shè)置為false關(guān)閉所有的hibernate二級緩存。但此屬性對指定<cache>的類缺省為true。 3. 為了使用二級緩存,需要在每一個Hibernate Entity上配置。 1.@Entity
2.@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE) 3.public class Forest { ... } 1.@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER) 2.@JoinColumn(name="CUST_ID") 3.@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE) 4.public SortedSet getTickets() { 5. return tickets; 6.} 1.@Cache( 2. CacheConcurrencyStrategy usage(); (1) 3. String region() default ""; (2) 4. String include() default "all"; (3) 5.) (1) usage: 提供緩存對象的事務(wù)隔離機制,可選值有以下幾種
(NONE, READ_ONLY, NONSTRICT_READ_WRITE, READ_WRITE, TRANSACTIONAL) (2) region (optional): 指定緩存的區(qū)域,默認(rèn)是類的全限定名。利用緩存區(qū)域,可以更精確的指定每個區(qū)域的緩存超前策略。如果指定了緩存區(qū)域前綴(在hibernate.cfg.xml中設(shè)置cache.region_prefix屬性為一個字符串),則所有的緩存區(qū)域名前將加上這個前綴。 (3) include (optional): all to include all properties, non-lazy to only include non lazy properties (default all). 如果不是使用annotation的話,則是在Hbm文件中添加cache usage="read-only" |
|
來自: 毀滅號 > 《hibernate》