代理是由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
非常感謝響應。請在此澄清一些疑問。這是什麼意思'使用代理使Hibernate只能加載所需的實例。「在這個例子中,需要的實例是什麼?我明白'batch-size'是在類級別上定義的,因此是否執行單個查詢來加載給定類的所有實例? – Chaitanya
我用例子編輯了我的答案,我希望現在更清楚。配置Hibernate記錄執行的SQL查詢,你會學到很多;) – Guillaume
真的很好的答案。我只是想知道它是否只在Cat處於持久化上下文時才起作用。它處於無狀態會話中,即使您調用Cat的方法,它仍然無法初始化。那是對的嗎?謝謝。 – rObOtAndChalie