Hibernate缓存级别教程
Hibernate提供了兩個(gè)緩存級(jí)別:
- 一級(jí)緩存是會(huì)話緩存。 對(duì)象被緩存在當(dāng)前會(huì)話中,并且它們僅在會(huì)話關(guān)閉之前是活動(dòng)的。
- 只要會(huì)話工廠處于活動(dòng)狀態(tài),第二級(jí)緩存就存在。 請(qǐng)記住,在Hibernate情況下,二級(jí)緩存不是對(duì)象樹。 對(duì)象實(shí)例不被緩存,而是存儲(chǔ)屬性值。
在簡(jiǎn)要介紹了一下Hibernate緩存之后(讓我知道這很簡(jiǎn)短),讓我們看一下什么是查詢緩存以及如何與二級(jí)緩存相關(guān)聯(lián)。
查詢緩存負(fù)責(zé)將作為參數(shù)提供的查詢和值的組合作為鍵進(jìn)行緩存,并將查詢執(zhí)行返回的對(duì)象的標(biāo)識(shí)符列表作為值進(jìn)行緩存。 注意,使用查詢緩存也需要二級(jí)緩存,因?yàn)閺木彺?#xff08;即標(biāo)識(shí)符列表)獲取查詢結(jié)果時(shí), Hibernate將使用二級(jí)緩存的標(biāo)識(shí)符加載對(duì)象。
概括起來(lái),作為一個(gè)概念性的模式,給出下一個(gè)查詢:“ from country from country>:number “,第一次執(zhí)行后, Hibernate緩存將包含下一個(gè)虛構(gòu)值(請(qǐng)注意,number參數(shù)設(shè)置為1000):
L2快取
[
id:1,{name ='Spain',人口= 1000,...。} id:2,{name ='德國(guó)',人口= 2000,...} …。 QueryCache [{來(lái)自人口>:number的國(guó)家/地區(qū),1000},{id:2}]
因此,在開始使用查詢緩存之前,我們需要配置第二級(jí)緩存。
首先,您必須確定要使用的緩存提供程序。 對(duì)于此示例,選擇了Ehcache ,但請(qǐng)參閱Hibernate文檔以獲取所有支持的提供程序的完整列表。
要配置二級(jí)緩存,請(qǐng)?jiān)O(shè)置下一個(gè)休眠屬性:
hibernate.cache.provider_class = org.hibernate.cache.EhCacheProvider
hibernate.cache.use_structured_entries = true
hibernate.cache.use_second_level_cache = true
如果您使用注釋方法,請(qǐng)使用以下方法注釋可緩存的實(shí)體:
@可緩存
@Cache(用法= CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
可以看到在這種情況下,緩存并發(fā)策略是NONSTRICT_READ_WRITE ,但是根據(jù)緩存提供者的不同,可以遵循其他策略,例如TRANSACTIONAL,READ_ONLY ………請(qǐng)查看Hibernate文檔的緩存部分,以選擇最適合您需求的策略。
最后添加Ehcache依賴項(xiàng):
<依賴性>
<groupId> net.sf.ehcache </ groupId>
<artifactId> ehcache-core </ artifactId> <version> 2.5.0 </ version> </ dependency> <依賴性> <groupId> org.hibernate </ groupId> <artifactId> hibernate-ehcache </ artifactId> <version> 3.6.0.Final </ version> </ dependency>
現(xiàn)在已配置了二級(jí)緩存,但未配置查詢緩存 ; 無(wú)論如何,我們離目標(biāo)不遠(yuǎn)。
將hibernate.cache.use_query_cache屬性設(shè)置為true 。
對(duì)于每個(gè)可緩存的查詢,我們必須在查詢創(chuàng)建期間調(diào)用setCachable方法:
List <Country> list = session.createQuery(“來(lái)自人口> 1000的國(guó)家/地區(qū)”).setCacheable(true).list();
為了使示例更實(shí)用,我已經(jīng)使用Spring Framework上傳了完整的查詢緩存示例。 為了清楚地了解查詢緩存的工作原理,我使用了一個(gè)在ensembl.org中托管的公共數(shù)據(jù)庫(kù)。 Ensembl項(xiàng)目為脊椎動(dòng)物和其他真核生物建立了基因組數(shù)據(jù)庫(kù),并在線免費(fèi)提供此信息。 在此示例中,對(duì)dna表的查詢被緩存。
首先進(jìn)行Hibernate配置:
@Configuration public class HibernateConfiguration {@Value("#{dataSource}")private DataSource dataSource;@Beanpublic AnnotationSessionFactoryBean sessionFactoryBean() {Properties props = new Properties();props.put("hibernate.dialect", EnhancedMySQL5HibernateDialect.class.getName());props.put("hibernate.format_sql", "true");props.put("hibernate.show_sql", "true");props.put("hibernate.cache.provider_class", "org.hibernate.cache.EhCacheProvider");props.put("hibernate.cache.use_structured_entries", "true");props.put("hibernate.cache.use_query_cache", "true");props.put("hibernate.cache.use_second_level_cache", "true");props.put("hibernate.hbm2ddl.auto", "validate");AnnotationSessionFactoryBean bean = new AnnotationSessionFactoryBean();bean.setAnnotatedClasses(new Class[]{Dna.class}); bean.setHibernateProperties(props);bean.setDataSource(this.dataSource);bean.setSchemaUpdate(true);return bean;}}這是一個(gè)簡(jiǎn)單的Hibernate配置,使用前面說(shuō)明的屬性來(lái)配置二級(jí)緩存。
實(shí)體類是代表DNA序列的實(shí)體。
@Entity(name="dna") @Cacheable @Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE) public class Dna {@Idprivate int seq_region_id;private String sequence;public int getSeq_region_id() {return seq_region_id;}public void setSeq_region_id(int seq_region_id) {this.seq_region_id = seq_region_id;}@Columnpublic String getSequence() {return sequence;}public void setSequence(String sequence) {this.sequence = sequence;}}為了嘗試查詢緩存 ,我們將實(shí)現(xiàn)一項(xiàng)測(cè)試,其中多次執(zhí)行同一查詢。
@Autowired private SessionFactory sessionFactory;@Test public void fiftyFirstDnaSequenceShouldBeReturnedAndCached() throws Exception {for (int i = 0; i < 5; i++) {Session session = sessionFactory.openSession();session.beginTransaction();Time elapsedTime = new Time("findDna"+i);List<Dna> list = session.createQuery("from dna").setFirstResult(0).setMaxResults(50).setCacheable(true).list();session.getTransaction().commit();session.close();elapsedTime.miliseconds(System.out);for (Dna dna : list) {System.out.println(dna);}} }我們可以看到我們正在返回前五十個(gè)dna序列,如果執(zhí)行它,您將看到打印了從查詢創(chuàng)建到提交事務(wù)之間的經(jīng)過(guò)時(shí)間。 如您所料,僅第一次迭代就需要大約5秒鐘來(lái)獲取所有數(shù)據(jù),而其他迭代只需數(shù)毫秒。
查詢迭代之前的foreach行將通過(guò)控制臺(tái)打印對(duì)象標(biāo)識(shí)符。 如果仔細(xì)觀察,這些標(biāo)識(shí)符將不會(huì)在所有執(zhí)行期間重復(fù)。 這個(gè)事實(shí)只是向您顯示Hibernate緩存不會(huì)保存對(duì)象而是保存屬性值,并且每次都會(huì)創(chuàng)建對(duì)象本身。
最后一點(diǎn),請(qǐng)記住,默認(rèn)情況下, Hibernate不緩存關(guān)聯(lián)。
現(xiàn)在,在編寫查詢之后,考慮它是否將包含靜態(tài)數(shù)據(jù)以及是否將經(jīng)常執(zhí)行。 在這種情況下, 查詢緩存是您的朋友,可以使Hibernate應(yīng)用程序運(yùn)行得更快。
下載代碼
參考:來(lái)自JCG合作伙伴的 Hibernate緩存級(jí)別教程 ? 在一個(gè)罐子統(tǒng)治他們所有博客的亞歷克斯·索托。
翻譯自: https://www.javacodegeeks.com/2012/02/hibernate-cache-levels-tutorial.html
總結(jié)
以上是生活随笔為你收集整理的Hibernate缓存级别教程的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 招商银行日日欣赎回多久到账?
- 下一篇: Apache Commons Lang