Hibernate查询缓存全面分析
?http://blog.csdn.net/security08/article/details/5670980
?
這里介紹Hibernate查詢緩存對Iterator不起作用,只對List起作用。
緩存分類:
◆一級緩存 Session級
◆二級緩存 SessionFactory級別,JVM級別
◆Hibernate查詢緩存不固定(生命周期不固定)
生命周期:
◆一級緩存 是和 session 會話一致產(chǎn)生一致消失
◆二級緩存 是和 sessionFacotry 一致
◆Hibernate查詢緩存 生命周期不固定,當(dāng)數(shù)據(jù)庫表發(fā)生改變,使用Hibernate查詢緩存馬上消失
使用方法:
◆一級緩存:這個(gè)就不用說了
◆二級緩存:首先拷貝使用Hibernate查詢緩存類別.xml到 classpath目錄下面,然后到hibernate.cfg.xml里面配置。開啟二級緩存(默認(rèn)開啟),定義要使用二級緩存的實(shí)體類,然后就是在程序中要顯示的指定session。使用二級緩存的類別 有三種,Normal,GET,PUT默認(rèn)使用的是 Normal即可以寫也可以讀取二級緩存(這里讀寫是指的會話Session)
◆Hibernate查詢緩存:首先也是到hibernate配置文件中去開啟Hibernate查詢緩存,然后程序中也要顯示的調(diào)用方法來開啟Hibernate查詢緩存eg:query.setCachemodel(true);
緩存的保存對象:
◆一級緩存:緩存實(shí)體
◆二級緩存:緩存的也是實(shí)體
◆Hibernate查詢緩存緩存的是查詢出來的實(shí)體的部分屬性結(jié)果集和實(shí)體的ID(注意這里不是實(shí)體)
緩存的使用對象:
◆一級緩存:
Load(Lazy加載):首先查找把序列號去和一級緩存匹配是否有,有就直接取出來,如果沒有,則發(fā)出SQL語句。
Get:也使用一級緩存。
List接口:query.list()不使用一級緩存,每次都要發(fā)出SQL eg:(select * from tudent)。
Iterator接口: query.iterate();使用一級緩存。首先是要發(fā)出一條SQL來取得ID,eg: select。id from student; 然后把ID拿到緩存中去匹配, 如果有,就直接取,如果沒有,就要再發(fā)出SQL。如果都沒有,將發(fā)出N+1條SQL,這就是N+1問題。
◆二級緩存: 都使用了二級緩存。
◆Hibernate查詢緩存:對List 和Iterator接口起作用。但是Hibernate查詢緩存對Iterator不起作用,只對List起作用。
?
下面我們這種介紹把二級緩存和Hibernate查詢緩存結(jié)合使用。
當(dāng)只是用Hibernate查詢緩存而關(guān)閉二級緩存的時(shí)候:
第一:如果查詢的是部分屬性結(jié)果集: 那么當(dāng)?shù)诙尾樵兊臅r(shí)候就不會發(fā)出SQL,直接從Hibernate查詢緩存中取數(shù)據(jù);
第二:如果查詢的是實(shí)體結(jié)果集eg(from Student) ,首先Hibernate查詢緩存存放實(shí)體的ID,第二次查詢的時(shí)候就到Hibernate查詢緩存中取出ID 一條一條的到數(shù)據(jù)庫查詢,這樣,將發(fā)出N 條SQL造成了SQL泛濫。
當(dāng)都開啟Hibernate查詢緩存和二級緩存的時(shí)候:
第一:如果查詢的是部分屬性結(jié)果集: 這個(gè)和上面只是用Hibernate查詢緩存而關(guān)閉 二級緩存的時(shí)候一致,因?yàn)椴簧婕皩?shí)體不會用到二級緩存;
第二:如果查詢的是實(shí)體結(jié)果集eg(from Student),首先Hibernate查詢緩存存放實(shí)體的ID,第二次查詢的時(shí)候,就到Hibernate查詢緩存中取出ID,到二級緩存區(qū)找數(shù)據(jù),如果有數(shù)據(jù),就不會發(fā)出SQL;如果都有,一條SQL都不會發(fā)出,直接從二級緩存中取數(shù)據(jù)。
?
總結(jié): 查詢緩存的key與HQL,查詢參數(shù)以及分布參數(shù)有關(guān),而且一旦查詢涉及到的任何一張表的數(shù)據(jù)發(fā)生了變化,緩存就失效了,所以在生產(chǎn)環(huán)境中命中率較低。查詢緩存保存的是結(jié)果集的id列表,而不是結(jié)果集本身 ,命中緩存的時(shí)候,會根據(jù)id一個(gè)一個(gè)地先從二級緩存查找 ,找不到再查詢數(shù)據(jù)庫。
list()沒有使用緩存中的實(shí)體對象,因?yàn)椴樵冃枰檎业剿蟹蠗l件的記錄,因此必須執(zhí)行SELECT SQL,來保證查詢數(shù)據(jù)的完整性;而iterate()通過執(zhí)行SELECT SQL語句來獲取滿足查詢條件的記錄的ID,來保證查詢數(shù)據(jù)的完整性
總結(jié)
以上是生活随笔為你收集整理的Hibernate查询缓存全面分析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JMS的两种消息模型(Point-to-
- 下一篇: spring 控制hibernate的s