Hibernate緩存的支持和使用情況
哪些方法支持Hibernate緩存
*get()
*load()
*iterate() (查詢實體對象)
save()
查詢緩存只對query.list()起作用
一級緩存測試:
1.Load測試: 在同一個session中發(fā)出兩次load查詢(1)
2.Get測試: 在同一個session中發(fā)出兩次get查詢(1)
3.iterate測試: 在同一個session中發(fā)出兩次iterator查詢(1(id)+N,1(id))
4.Iterate查詢屬性測試: 同一個session中發(fā)出兩次查詢屬性(2次,iterate查詢普通屬性,一級緩存不會緩存,所以會發(fā)出sql)
5.同一個session中先save,再發(fā)出load查詢save過的數(shù)據(jù)--save是使用緩存的
6.同一個session中先調(diào)用load查詢,然后執(zhí)行sessio.clear()或session.evict(),再調(diào)用load查詢(2次)
sessio.clear()或session.evict()可以管理一級緩存,一級緩存無法取消,但可以管理. 上面的語句都會發(fā)出sql 因為一級緩存中的實體被清除了
7.向數(shù)據(jù)庫中批量加入1000條數(shù)據(jù)
//每一定條數(shù)據(jù)就強制session將數(shù)據(jù)持久化,同時清除緩存,避免大量數(shù)據(jù)造成內(nèi)存溢出
開啟二級緩存測試:
1.開啟兩個session中發(fā)出兩次load查詢(get與load一樣,1次),
2.開啟兩個session,分別調(diào)用load,再使用sessionFactory清楚二級緩存(2次)
3.一級緩存和二級緩存的交互
session.setCacheMode(CacheMode.GET); //設置成 只是從二級緩存里讀,不向二級緩存里寫數(shù)據(jù) (2)
session.setCacheMode(CacheMode.PUT); //設置成只是向二級緩存里寫數(shù)據(jù),不讀數(shù)據(jù) (2次)
Hibernate緩存查詢測試:開啟hibernate查詢緩存測試:
1. 開啟查詢緩存,關閉二級緩存,開啟一個session,分別調(diào)用query.list (查詢屬性)(1次)
2. 開啟查詢緩存,關閉二級緩存,開啟兩個session,分別調(diào)用query.list (查詢屬性)
(1次)第二次沒有去查詢數(shù)據(jù)庫,因為查詢緩存生命周期與session生命周期無關
3. 開啟查詢緩存,關閉二級緩存,開啟兩個session,分別調(diào)用query.iterate (查詢屬性)
(2次)第二去查詢數(shù)據(jù)庫,因為查詢緩存只對query.list()起作用,對query.iterate()不起作用,也就是說query.iterate()不使用查詢緩存
4. 關閉查詢緩存,關閉二級緩存,開啟兩個session,分別調(diào)用query.list (查詢實體對象) 第二去查詢數(shù)據(jù)庫,因為list默認每次都會發(fā)出查詢sql
5. 開啟查詢緩存,關閉二級緩存,開啟兩個session,分別調(diào)用query.list (查詢實體對象) 第二去查詢數(shù)據(jù)庫時,會發(fā)出N條sql語句,因為開啟了查詢緩存,關閉了二級緩存,那么查詢緩存會緩存實體對象的id,所以hibernate會根據(jù)實體對象的id去查詢相應的實體,如果緩存中不存在相應的實體,那么將發(fā)出根據(jù)實體id查詢的sql語句,否則不會發(fā)出sql,使用緩存中的數(shù)據(jù)
6. 開啟查詢緩存,開啟二級緩存,開啟兩個session,分別調(diào)用query.list (查詢實體對象) 第二不會發(fā)出sql,因為開啟了二級緩存和查詢緩存,查詢緩存緩存了實體對象的id列表,hibernate會根據(jù)實體對象的id列表到二級緩存中取得相應的數(shù)據(jù)
二級緩存在項目中的集成和使用
1.將echcache.xml文件拷貝到src下, 二級緩存hibernate默認是關閉的,手動開啟
2.開啟二級緩存,修改hibernate.cfg.xml文件,
< property name=”hibernate.cache.user_second_level_cache”>true< /property>
3.指定緩存產(chǎn)品提供商
< property name=”hibernate.cache.provider_calss”>org.hibernate.cache.EhCacheProvider< /property>
4.指定那些實體類使用二級緩存(兩種方法,推薦使用第二種)
***種:在*.hbm.xml中,在< id>之前加入
< cache usage=”read-only” />, 使用二級緩存
第二種:在hibernate.cfg.xml配置文件中,在< mapping resource=”com/Studnet.hbm.xml” />后面加上:
< class-cache class=” com.Studnet” usage=”read-only” />
總結(jié):
不要想當然的以為Hibernate緩存一定能提高性能,僅僅在你能夠駕馭它并且條件合適的情況下才是這樣的。hibernate的二級緩存限制還是比較多的,不方便用jdbc可能會大大的降低更新性能。在不了解原理的情況下亂用,可能會有1+N的問題。不當?shù)氖褂眠€可能導致讀出臟數(shù)據(jù)。
如果受不了hibernate的諸多限制,那么還是自己在應用程序的層面上做緩存吧。
在越高的層面上做緩存,效果就會越好。就好像盡管磁盤有緩存,數(shù)據(jù)庫還是要實現(xiàn)自己的緩存,盡管數(shù)據(jù)庫有緩存,咱們的應用程序還是要做緩存。因為底層的緩存它并不知道高層要用這些數(shù)據(jù)干什么,只能做的比較通用,而高層可以有針對性的實現(xiàn)緩存,所以在更高的級別上做緩存,效果也要好些吧。
對于性能的看法是:合理的性能而不是***的性能。什么是合理的?用戶能感覺到(或敏感的)的范圍內(nèi),不成為物理上業(yè)務處理的瓶頸,比如常說的3秒之內(nèi)響應等。
【編輯推薦】