標籤:hibernate緩衝配置 hibernate一級緩衝 hibernate二級緩衝
【Hibernate】一級、二級緩衝
Hibernate緩衝按層級共分為兩種,一級緩衝(Session)和二級緩衝(SessionFactory),有的也說是三種,還有一種是查詢緩衝,當然,查詢緩衝是依託於二級緩衝。
ok,什麼是緩衝?
在記憶體裡開闢一塊空間把本來應該存在硬碟裡面的資料,存在這個空間裡面,將來,需要這塊資料的時候直接在記憶體中擷取。這個就可以簡單理解為緩衝。
一級緩衝
什麼是一級緩衝,一級緩衝是Hibernate預設的,不用管它。
比如下面這段代碼,
@Test publicvoid findTestyijihuanchong(){ Session s=sessionFactory.openSession(); s.beginTransaction(); Person person=(Person)s.load(Person.class, 1); System.out.println(person.getName()); //因為Session存在緩衝,所以這個查詢直接在session中取 Person person2=(Person)s.load(Person.class, 1); System.out.println(person2.getName()); s.getTransaction().commit(); }
我們發現,只會發出一條sql語句,那麼這個就是Hibernate內建的一級緩衝。
那比如下面這種情況,新開的Session呢?在系統中,多線程並發的時候,肯定不止產生一個Session,所以在最佳化效能時,一級緩衝往往滿足不了需求,那麼就有了二級緩衝
比如下面這段代碼,顯然發出的是兩條SQL語句。
@Test publicvoidfindTestyijihuanchong(){ Sessions=sessionFactory.openSession(); s.beginTransaction(); Personperson=(Person)s.load(Person.class, 1); System.out.println(person.getName()); s.getTransaction().commit(); s.close(); Sessions2=sessionFactory.openSession(); s2.beginTransaction(); Personperson2=(Person)s2.load(Person.class, 1); System.out.println(person2.getName()); s2.getTransaction().commit(); s2.close(); }
二級緩衝
什麼是二級緩衝?二級緩衝也可以理解為SessionFactory層級的緩衝,SessionFactory是生產Session的工廠,那麼我們可不可以這麼理解,Session關聯一個指向資料庫的結果集,那麼下次我在發SQL的時候,我發現,SessionFactory裡面已經有了一個指向這個結果集的語句,那麼我是不是可以直接使用了!
具體來說,二級緩衝並不是由Hibernate來提供,是由第三方提供的緩衝外掛程式,通常有以下幾種第三方緩衝外掛程式:
EhCache:可作為進程範圍的緩衝,存放資料的物理介質可以是記憶體或硬碟,對Hibernate的查詢快取提供了支援。
OSCache:可作為進程範圍的緩衝,存放資料的物理介質可以是記憶體或硬碟,提供了豐富的快取資料到期策略,對Hibernate的查詢快取提供了支援。
SwarmCache:可作為群集範圍內的緩衝,但不支援Hibernate的查詢快取。
JBossCache:可作為群集範圍內的緩衝,支援事務型並發存取原則,對Hibernate的查詢快取提供了支援。
那麼,哪些資料適合放在二級緩衝中,理解二級緩衝特性之後,我們知道,
1、經常被查詢的資料,這樣的資料需要頻繁訪問資料庫,肯定是非常適合放在緩衝
2、很少並發的資料,什麼意思呢?打個比方,一個查詢,一個修改,這樣很可能會造成一種髒讀,或者是幻讀。意思就是你的資料庫的資料可能被修改了,但是設定二級緩衝還沒有及時更新
3、重要的資料,這個不多說
總之,放在二級緩衝中的資料,一般都是不重要的,不經常修改的資料。比如說,菜單,比如說許可權。這些都是非常適合放在二級緩衝中,比如說財務資料,工資資料等,這些不建議放在二級緩衝中
我們上面講了二級緩衝是第三方提供的那麼顯然我們需要配置,
首先我們需要在我們的hibernate.cfg.xml中開啟我們的二級緩衝,當然也可能是properties檔案中配置
<!-- 開啟緩衝 --><property name="hibernate.cache.use_second_level_cache">true</property><!--指定是哪個二級緩衝--><property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property><!-- 使用查詢二級緩衝 --><propertyname="hibernate.cache.use_query_cache">true</property>
第二步,我們指定是哪個實體類需要二級緩衝
Annotations配置
@Entity@Cache(usage=CacheConcurrencyStrategy.READ_WRITE)@Table(name="p_person")
XML配置
<class name="Person" table="t_person"> <cache usage="read-write"/> <id name="id">
記住XML配置一定是id之前,class之內
還必須有ehcache.xml檔案,這個檔案有興趣大家可以在網上自己看一下,這裡我就不講解,裡面的內容了
配置完之後,我們直接看
@Test publicvoid findTesterjihuanchong(){ Sessions=sessionFactory.openSession(); s.beginTransaction(); Personperson=(Person)s.load(Person.class, 1); System.out.println(person.getName()); s.getTransaction().commit(); s.close(); Sessions2=sessionFactory.openSession(); s2.beginTransaction(); Personperson2=(Person)s2.load(Person.class, 1); System.out.println(person2.getName()); s2.getTransaction().commit(); s2.close(); }
這個時候,我們再看,肯定又是只發送一條SQL語句了。
查詢緩衝
什麼是查詢查詢緩衝。顧明思議它是查詢的時候產生的緩衝,那我們前面講到了二級緩衝,查詢緩衝和二級緩衝是什麼關係?首先查詢緩衝是依賴於二級緩衝的,查詢緩衝一般設定在list()方法中,查詢緩衝是重複查詢使用的緩衝,如果你兩個查詢不一樣,這個存在的緩衝是不起作用的。需要注意的是list()查詢緩衝必須要告訴hibernate,使用查詢緩衝,查詢緩衝才會生效。
setCacheable(true)
ok,看代碼
@Test publicvoid findTestList(){ Sessions=sessionFactory.getCurrentSession(); s.beginTransaction(); List<Person>persons=s.createQuery("fromPerson").setCacheable(true).list(); List<Person>person1=s.createQuery("fromPerson").setCacheable(true).list(); for(Person person:persons){ System.out.println(person.getName()+"----"+person.getId()); } for(Person person:person1){ System.out.println(person.getName()+"----"+person.getId()); } s.getTransaction().commit(); }
到這裡,我們基本上做完了Hibernate緩衝,但是緩衝怎麼配置,怎麼使用,要根據實際的項目情況而定,並不是說,配置了二級緩衝一定會提高系統效能。同時,進階的可能也牽涉到緩衝演算法等問題。當然在項目中多犯幾次錯誤,自然就會使用Hibenrate緩衝了!
下篇博文寫悲觀鎖和樂觀鎖,寫完之後,我會寫一篇怎麼模仿開發一套屬於我們自己ORM架構,基本上就寫完了Hibenrate的常見特性,閑來無事,喜歡寫著玩,大家隨便看,有問題及時探討。
本文出自 “諾言永遠依戀小柴、、、” 部落格,請務必保留此出處http://1936625305.blog.51cto.com/6410597/1577057
hibernate之關於Hibernate的一級、二級緩衝