標籤:檢索策略 -- cti 不同 取值 on() action 條件查詢 語句
一.概述
我們先來談談檢索資料時的兩個問題:
1.不浪費記憶體 2.更好的檢索效率
以上說的問題都是我們想要避免的,接下來就引出了我們要討論的話題---------------hibernate檢索策略
二.hibernate檢索策略分為三種:
1.類層級的檢索策略
2.一對多和多對多檢索策略
3.多對一和一對一關聯的檢索策略
(1)類層級的檢索策略分為立即檢索和延遲檢索,預設為延遲檢索。
立即檢索:立即載入檢索方法指定的對象,立即發送SQL.
延遲檢索:消極式載入檢索方法指定的對象,在使用具體的對象時,再進行載入,發送SQL.
lazy有兩個取值:false(立即載入) 和 true(消極式載入)
討論一:當用get()方法檢索資料時,在類層級檢索策略不管是不是消極式載入都會立即檢索
接下來看看代碼實現是不是跟我說的一樣:
設定檔中:
測試類別代碼:
@Test public void select1(){ Session session = HibernateUtil.currentSession(); Transaction tx = session.beginTransaction(); House house = session.get(House.class, 1); System.out.println("==========================="); // System.out.println(house.getType().getName()); tx.commit(); HibernateUtil.closeSession(); }
接下來看看測試的效果:
接下來我們把lazy設為true:
效果:
大家注意沒,測試類別有一行代碼我是注釋掉的,為的就是讓我們很好的理解,如果我把下面的代碼放開是什麼效果呢?大家要注意現在我們的查詢是get()方法:
我們得到的結果是一樣的,這樣就說明了當使用類層級檢索時,使用get()方法都會立即載入。
討論二:我們在來看看load()方法(也是類層級的檢索),我們只需要修改代碼即可:
@Test public void select1(){ Session session = HibernateUtil.currentSession(); Transaction tx = session.beginTransaction(); House house = session.load(House.class, 1); System.out.println("=========lazy:false=================="); //System.out.println(house.getType().getName()); tx.commit(); HibernateUtil.closeSession(); }
lazy:false時:
我們把lazy設為true時效果如下:
我們看到只列印了分割線,到這裡我們可以看出get()和load()方法在類層級檢索時的區別,接下來我們看看當放開注釋的代碼時會發生什麼呢?
我們可以很直觀的看出來,得到的結果不一樣,當消極式載入的情況下,當我們有後續操作時才會向資料庫發送SQL,查詢結果。而立即載入在我們有後續操作之前,已經先查詢了一道,然後再根據後續操作查詢結果。
通過以上我們做的測試,我們可以得出一個結論:
當類層級檢索時:get()方法不管消極式載入還是消極式載入都會先查詢一道,有後續操作再向資料庫發送SQL,得到結果。
load()方法:當是消極式載入的情況下,有後續操作才會向資料庫發送SQL,查詢結果。
當是立即載入的情況下,就和get()方法一樣,先查詢一道,有後續從操作在查詢。
總的來說,load()方法受類層級檢索策略影響,get()方法不受影響。
(2)一對多和多對多檢索策略
在對應檔中,用<set>元素來配置一對多和多對多關聯關係
lazy取值有:false(立即載入),true(消極式載入)和extra(加強消極式載入)
設定檔:
測試類別代碼:
@Test public void select(){ Session session = HibernateUtil.currentSession(); Transaction tx = session.beginTransaction(); House house = session.load(House.class, 1); System.out.println("==========lazy:false==================="); System.out.println(house.getClass()); // System.out.println(house.getTitle()); tx.commit(); HibernateUtil.closeSession(); }
先來看看當我們使用load()載入資料時,我們輸出的結果:
當lazy取值為false:
當lazy取值為true:
都沒有後續操作時,沒有不同。接下來我們看一下當有後續操作時(解開注釋的代碼),會發生什嗎?
lazy:true時:
lazy為false時:
我們可以明顯的看出這兩個的不同,消極式載入時發送了一條SQL,立即載入時發送了兩條SQL,消極式載入的後續操作是根據你的條件查詢的,立即載入根據你的條件查詢之後,如果有與之相關的表,也會進行兩表查詢。
get()方法擷取時,沒有後續操作:
lazy:true
lazy:false:
當有後續操作時,看看是什麼情況?
lazy:true時,
lazy:false時,
由此可以看出,當使用get()方法時,不管有沒有後續操作,都會先向資料庫發送SQL語句,儲存對象的資訊,而且我們也看出來不管load()和get()在立即載入情況下,會向資料庫發送SQL,根據你查詢對象所關聯的表的個數來決定向資料庫發送幾條SQL語句,(我列舉的例子是發送兩條)。
Hibernate 檢索策略