2014-01-08 27 views
19

load()方法Hibernate文檔說:什麼是在Hibernate的load()方法的上下文中的代理?

注意如果 沒有匹配的數據庫記錄該負載()將拋出一個不可恢復的異常。 如果該類使用代理進行映射,則load() 只會返回一個未初始化的代理,並且實際上並不會觸發 數據庫,直到您調用該代理的一個方法爲止。 如果你想 希望創建一個到對象的關聯而不實際從數據庫中加載它 ,這很有用。如果爲類映射定義了批處理大小,它還允許將多個實例作爲批處理加載 。

請幫我理解這個被解釋部分的含義在大膽上文所強調的。

回答

43

代理是由Hibernate動態生成的類,用於延遲加載。例如,如果你有一個Cat類,Hibernate將生成一個擴展Cat的代理類。

如果你得到這個代理的一個未初始化的實例,基本上它的所有字段都是空的,因爲Hibernate還沒有命中數據庫。現在你第一次調用這個代理的方法時,它會意識到它沒有被初始化,它會查詢數據庫來加載它的屬性。這是可能的,因爲動態生成的類會覆蓋基類的方法並添加此初始化/未初始化的檢查。

現在假設您的Cat類不是代理,並且它具有father關聯,當您加載Cat對象時,Hibernate將需要加載它的所有屬性。所以如果你加載一個Cat對象,Hibernate也需要加載它的父親和父親的父親等等。使用代理使Hibernate只能加載所需的實例。

Cat cat1 = (Cat) session.load(1); 
Cat cat2 = (Cat) session.load(2); 
Cat cat3 = (Cat) session.load(3); 

cat1.meow(); // this will cause Hibernate to run a query to load cat1's data 
cat2.meow(); // this will cause Hibernate to run a query to load cat2's data 

// After this cat3 is still an uninitiated proxy because it has not been used 

batch-size是休眠的另一個特徵是,在大多數情況下,幫助處理延遲加載。基本想法是,休眠保持未初始化的代理的跟蹤和時的需求之一被初始化,一個單一的查詢將被執行加載高達batch-size代理(而不是僅僅一個代理/查詢)

Cat cat1 = (Cat) session.load(1); 
Cat cat2 = (Cat) session.load(2); 

cat1.meow(); // if batch-size >= 2, cat1 and cat2 will be loaded in a single query 
cat2.meow(); // no query will be executed here 
+0

非常感謝響應。請在此澄清一些疑問。這是什麼意思'使用代理使Hibernate只能加載所需的實例。「在這個例子中,需要的實例是什麼?我明白'batch-size'是在類級別上定義的,因此是否執行單個查詢來加載給定類的所有實例? – Chaitanya

+1

我用例子編輯了我的答案,我希望現在更清楚。配置Hibernate記錄執行的SQL查詢,你會學到很多;) – Guillaume

+0

真的很好的答案。我只是想知道它是否只在Cat處於持久化上下文時才起作用。它處於無狀態會話中,即使您調用Cat的方法,它仍然無法初始化。那是對的嗎?謝謝。 – rObOtAndChalie

4

這類似於關聯的延遲加載,但可能更多地被視爲「懶惰創建」。

代理是在運行時實現的子類。 Hibernate創建一個代理(被提取的類的一個子類),而不是直接查詢數據庫,並且只要調用其中一個方法,該代理就會從數據庫加載「真實」對象。

第二個突出顯示的文本解釋說,如果您在多個實例上調用load(),則可以將它們作爲批處理來獲取它們,並以此方式減少往返數據庫的往返行程。

這也是負載之間()和get()負載排序懶加載對象的差異,而從數據庫獲取的對象馬上

+0

thx用於加載和獲取之間的差異。 – DevdattaK

相關問題