抓取策略(Fetching strategies)

Technorati 標籤: hibernate,fetch,lazy

Hibernate 3.3.2.GA

hibernate檢索策略是指hibernate加載關聯對象的策略,hibernate3抓取關聯對象有3種方式

 

連接抓取(join fetching):fetch="join", 在獲取主對象的同時,通過外連接的方式獲得關聯對象,不會形成多次查詢。
查詢抓取(select fetching): fetch="select", 先獲取主對象,然後根據關聯id執行select查詢獲取關聯對象。


子查詢抓取 (subclass fetching): fetch="subselect", 通過子查旬而不是外連接獲取關聯對象。

檢索策略是指在什麼時候採用什麼樣的方式獲取關聯對象。有3 種:


立即檢索(eager loading):在獲取主對象的同時立即獲得關聯對象。一前面的one-to- many的Member和Order爲例,一個Member對應多個Order.
<set name="orders" cascade="all" lazy="false">,則Member m = dao.getById(4);就會立即加載orders.


延遲加載(lazy loading):和立即檢索相對應,只有在用到關聯對象的時候才加載。
<set name="orders" cascade="all" lazy="true">,則Member m = dao.getById(4);就不會立即加載orders。


預先抓取(pre fetching):通過配置fetch="join",通過外連接獲取關聯對象。
<set name="orders" cascade="all" fetch="join"> 則Member m = dao.getById(4);hibernate通過left outer join獲取orders.


抓取方式和檢索策略這兩種行爲方式或者概念我混淆了好久。其實他們是不同的東西,需要多體會。通常改變fetch的取值會改變最終產生的sql,檢索策略會影響關聯對象的獲取時機(也會影響到sql)。

fetch (optional - defaults to join): if set to join, the default, Hibernate will use an inner join to retrieve a <join> defined by a class or its superclasses. It will use an outer join for a <join> defined by a subclass. If set to select then Hibernate will use a sequential select for a <join> defined on a subclass. This will be issued only if a row represents an instance of the subclass. Inner joins will still be used to retrieve a <join> defined by the class and its superclasses.

下面根據關聯關係的不同,分情況討論一下檢索策略和抓取方式的應用。


多對一(many- to-one):應該優先考慮預先抓取,他比立即檢索少使用了sql, 有助於提高性能。但是fetch和lazy可以有不同的組合

 

一對一(one-to-one): 應該優先考慮預先抓取,而且hibernate默認是預先抓取. hibernate one-to-one的實現比較特殊,要設置<one-to-one>的constrained='true',  同時被關聯的class的lazy='true'.

 

一對多/多對多(one-to-many/many-to-many): 優先考慮延遲加載.

 

fetch(可選-默認值是join):如果設置爲join,hibernate將使用inner join(內連接)

如果關聯的字段被設置爲 not-null = “true” ,則爲內連接的方式獲取關聯對象如

如果不設置not-null,則採用 left outer join的方式獲取關聯對象

 

fetch="select " 是用來告訴Hibernate,在查詢超類時, 不要使用外部連接(outer join)來抓取子類的數據。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章