Hibernate深入之get()與load()懶載入
一個是直接載入,並不是直接去資料庫查詢,如果快取裡有,首先到快取裡找,快取分為一級快取和二級快取,首先到一級快取中查詢;
如果在session關閉之後進行獲取類的名字之類的屬性,依然會獲取到,例:
Order od = (Order) session.get(Order.class, 1);
通過get獲取的Order類是一個持久化類,如果session關閉之後進行獲取,od.getName,它就會變成託管狀態,但是這個物件還是有的,所以沒事;
另一個是懶載入,他不會直接進行操作,就是除了獲取id(識別符號)和類.class時,獲取其他的類屬性都會進行操作,
例:
Account acc=(Account)session.load(Account.class,new Long(1)); //返回一個代理物件
System.out.println(acc.getId);
System.out.prontln(acc.getLonginName());
這裡的1是一個代理物件,如果只獲取他的id,則不會載入,不會出現select語句,只有獲取除他和本身之外才會進行查詢;否則訪問的只是他的代理物件而已;如果需要取消懶載入,就只需要在你想獲取的類屬性的對映檔案的<class name=”” table=”” lazy=”false”>把他改為false就可以了,這樣懶載入就取消了,這裡只對load管用,對get()毫無影響;
如果把他System.out.prontln(acc.getLonginName());
接下來說一說他們之間的區別,
延遲載入的過程:通過代理(Proxy)機制來實現延遲載入。Hibernate從資料庫獲取某一個物件資料時、獲取某一個物件的集合屬性值時,或獲取某一個物件所關聯的另一個物件時,由於沒有使用該物件的資料(除識別符號外),Hibernate並不從資料庫載入真正的資料,而只是為該物件建立一個代理物件來代表這個物件,這個物件上的所有屬性都為預設值;只有在真正需要使用該物件的資料時才建立這個真正的物件,真正從資料庫中載入它的資料。
如果只是訪問物件標示符屬性,就沒有必要初始化程式碼。
Account acc=(Account)session.load(Account.class,new Long(1)); //返回一個代理物件
Order order=new Order();
order.setCreateTime(new Date());
order.setAccount(acc);
Session.save(order);
在這隻需要Account例項來建立一個新的Order訂單物件,當呼叫session.save(order)時,也只需要Account的主標示符值作為外來鍵儲存到訂單表的對應欄位中。這樣就少執行一條select語句,從而提高查詢效率。
Hibernate中預設採用延遲載入的情況主要有以下幾種:
當呼叫Session上的load()方法載入一個實體時,會採用延遲載入。
當Session載入某個實體時,會對這個實體中的集合屬性值採用延遲載入。(one-to-many)
例:當Client這個類裡具有集合屬性,
Client client = (Client) session.get(Client.class, 4);
System.out.println(client.getName());
獲取他的名字,你會發現只有一條sql語句,因為採用了延遲載入,所以如果想
取消,就在該對映檔案下<set>裡面把lazy改成false;
當Session載入某個實體時,會對這個實體所單端關聯(one-to-one, many-to-one)的另一個實體物件採用延遲載入。
能夠懶載入的物件都是被改寫過的代理物件,當相關聯的session沒有關閉時,訪問這些懶載入物件(代理物件)的屬性(getId和getClass除外)hibernate會初始化這些代理,或用Hibernate.initialize(proxy)來初始化代理物件;當相關聯的session關閉後,再訪問懶載入的物件將出現異常。
2、 關閉延遲載入
在載入單個實體時,如果不需要延遲載入,就可以使用session的get()方法。
當Session載入某個實體時,不需要對這個實體中的集合屬性值延遲載入,而是要立即載入。這時可以在對映檔案中針對 這個集合屬性的配置元素(<set>,<bag>,<list>…)新增屬性lazy=“false”。
當Session載入某個實體時,不需要對這個實體所單端關聯的另一個實體物件延遲載入,就可以在對映檔案中對這個單端關聯的配置元素(<one-to-one>,<many-to-one> )新增屬性lazy=“false”。
注意:one-to-one不能有constrained=true