標籤:ref style student query mod 是什麼 log ora 記錄
我的上一篇部落格Hibernate緩衝體系之查詢快取(query cache),以及list和iterate方法的差別介紹了查詢快取的概念,以及list和iterate的差別。讀者可能注意到:那篇部落格測試的前提是,僅僅開啟查詢快取,沒有開啟二級緩衝。
通過各種情形測試,我們能夠得出一個結論:僅僅開啟查詢快取。不開啟二級緩衝是沒有意義的。
為什麼這麼說呢?上一篇部落格能夠看出。不開啟二級緩衝,iterate()方法存在N+1次資料庫查詢問題,list方法最多僅僅能命中id。也須要N次資料庫查詢,不管是哪兒種情況,查詢快取已經失去了意義。這篇部落格我們開啟二級緩衝的情況下。將上篇部落格的情況再測試下。看下會是什麼效果。
hibernate4.1.6在hibernate.cfg.xml進行例如以下配置,能夠開啟二級緩衝。
<property name="cache.use_second_level_cache">true</property><property name="cache.region.factory_class">org.hibernate.cache.EhCacheRegionFactory</property>
因為測試代碼和資料庫都和上篇部落格一模一樣。唯一不同就是開啟了二級緩衝。這裡不再附代碼。直接通過測試結果來分析結論。
1. 2次list()運行結果分析
testUseList()運行結果例如以下:
Hibernate: select student0_.id as id0_, student0_.name as name0_, student0_.age as age0_ from Student student0_ where student0_.name=‘zhangsan111‘list語句測試query cache:[email protected][id=1, name=zhangsan111, age=18]list語句測試query cache:[email protected][id=2, name=zhangsan111, age=18]list語句測試query cache:[email protected][id=3, name=zhangsan111, age=18]-------list進行第二次查詢------list語句測試query cache:[email protected][id=1, name=zhangsan111, age=18]list語句測試query cache:[email protected][id=2, name=zhangsan111, age=18]list語句測試query cache:[email protected][id=3, name=zhangsan111, age=18]
能夠發現list()第一次發出1條sql語句。第二次查詢沒有訪問資料庫,直接從緩衝中擷取的資料。
在開啟查詢快取和二級緩衝的情況下,list將擷取到的id放入查詢快取,key是sql語句。將實體物件放入二級緩衝,key是實體物件的主索引值。list會首先依據sql語句去查詢快取中擷取id,假設沒有擷取到則發出1條sql查詢語句,查詢出全部須要的欄位值。
2. 2次iterate()運行結果分析
testUseIterator()運行結果例如以下:
<span style="font-size:14px;">Hibernate: select student0_.id as col_0_0_ from Student student0_ where student0_.name=‘zhangsan111‘Hibernate: select student0_.id as id0_0_, student0_.name as name0_0_, student0_.age as age0_0_ from Student student0_ where student0_.id=?iterate語句測試query cache:[email protected][id=1, name=zhangsan111, age=18]Hibernate: select student0_.id as id0_0_, student0_.name as name0_0_, student0_.age as age0_0_ from Student student0_ where student0_.id=?iterate語句測試query cache:[email protected][id=2, name=zhangsan111, age=18]Hibernate: select student0_.id as id0_0_, student0_.name as name0_0_, student0_.age as age0_0_ from Student student0_ where student0_.id=?iterate語句測試query cache:[email protected][id=3, name=zhangsan111, age=18]-------iterate進行第二次查詢------Hibernate: select student0_.id as col_0_0_ from Student student0_ where student0_.name=‘zhangsan111‘iterate語句測試query cache:[email protected][id=1, name=zhangsan111, age=18]iterate語句測試query cache:[email protected][id=2, name=zhangsan111, age=18]iterate語句測試query cache:[email protected][id=3, name=zhangsan111, age=18]</span>
第一次iterate()查詢,因為查詢快取和二級緩衝中都沒有資料,須要進行N+1次資料庫查詢;第二次查詢,僅僅發出一條sql查詢主索引值,興許依據主索引值從二級緩衝中擷取具體資訊。
iterate方法會將擷取到的實體物件存入二級緩衝。至於是否會將id存入查詢快取,這裡還不能確定,只是能夠肯定的是。iterate不會利用查詢快取中的id值。而是每次查詢都又一次使用sql查詢滿足條件的記錄主索引值。之後再依據主鍵從二級緩衝中查詢實體物件。
3. 先iterate後list運行結果分析
testIteratorAndList1()運行結果例如以下:
<span style="font-size:14px;">Hibernate: select student0_.id as col_0_0_ from Student student0_ where student0_.name=‘zhangsan111‘Hibernate: select student0_.id as id0_0_, student0_.name as name0_0_, student0_.age as age0_0_ from Student student0_ where student0_.id=?iterate語句測試query cache:[email protected][id=1, name=zhangsan111, age=18]Hibernate: select student0_.id as id0_0_, student0_.name as name0_0_, student0_.age as age0_0_ from Student student0_ where student0_.id=?iterate語句測試query cache:[email protected][id=2, name=zhangsan111, age=18]Hibernate: select student0_.id as id0_0_, student0_.name as name0_0_, student0_.age as age0_0_ from Student student0_ where student0_.id=?iterate語句測試query cache:[email protected][id=3, name=zhangsan111, age=18]-------第一次使用iterate,第二次使用list查詢------Hibernate: select student0_.id as id0_, student0_.name as name0_, student0_.age as age0_ from Student student0_ where student0_.name=‘zhangsan111‘list語句測試query cache:[email protected][id=1, name=zhangsan111, age=18]list語句測試query cache:[email protected][id=2, name=zhangsan111, age=18]list語句測試query cache:[email protected][id=3, name=zhangsan111, age=18]</span>
這裡能夠看出,iterate的緩衝資訊對於list是沒有協助的。list會發出1條sql。從資料庫中查詢全部須要的欄位值。這裡能夠看出:
iterate方法不會將主索引值放到查詢快取中,由於假設放入查詢快取的話。這裡的list是沒有必要再發出sql查詢的。
4. 先list後iterate運行結果分析
testIteratorAndList2()運行結果例如以下:
<span style="font-size:14px;">Hibernate: select student0_.id as id0_, student0_.name as name0_, student0_.age as age0_ from Student student0_ where student0_.name=‘zhangsan111‘list語句測試query cache:[email protected][id=1, name=zhangsan111, age=18]list語句測試query cache:[email protected][id=2, name=zhangsan111, age=18]list語句測試query cache:[email protected][id=3, name=zhangsan111, age=18]-------第一次使用list,第二次使用iterate查詢------Hibernate: select student0_.id as col_0_0_ from Student student0_ where student0_.name=‘zhangsan111‘iterate語句測試query cache:[email protected][id=1, name=zhangsan111, age=18]iterate語句測試query cache:[email protected][id=2, name=zhangsan111, age=18]iterate語句測試query cache:[email protected][id=3, name=zhangsan111, age=18]</span>
這裡可以得出的結論,跟2次list()查詢幾乎相同。
唯一的區別是:iterate每次查詢都會發出查詢實體物件id的sql語句。
5. 總結
通過開啟查詢快取和二級緩衝,相同的sql查詢可以直接使用查詢快取中的id和二級緩衝中的實體物件,可以有效降低反覆的資料庫查詢,可以提高查詢效率。也就是說:同一時候開啟查詢快取和二級緩衝是有意義的。也是實際使用hibernate的最佳配置。
進一步的。我們也能夠看出list和iterate方法的差別。list()會將實體物件的id放入查詢快取,將實體物件本身放入二級緩衝。iterate不會將實體物件的id放入查詢快取。可是會將實體物件本身存入二級緩衝。
假設第二次查詢可以命中的情況下:list全然不須要查詢資料庫,可以先從查詢快取中擷取到id。再從二級緩衝中擷取實體物件。iterate一定會發出一條查id的sql,然後去二級緩衝中擷取實體物件。
至此hibernate的二級緩衝、查詢快取的關係已經講完。list和iterate差別也已經測試出。
希望能對大家有協助,假設錯誤。歡迎大牛們指正。
hibernate的查詢快取和二級緩衝的配合使用