Hibernate的fetch (轉)

fetch ,能夠設置fetch = "select" 和 fetch = "join"

用一對多來舉例:
fetch = "select"是在查詢的時候先查詢出一端的實體,而後在根據一端的查詢出多端的實體,會產生1+n條sql語句;
fetch = "join"是在查詢的時候使用外鏈接進行查詢,不會差生1+n的現象。

lazy你們應該都熟悉了,就是延遲加載,能夠設置lazy = "true" , lazy = "false" lazy = "proxy" 。
我在這裏要說的主要問題是lazy 和fetch配合使用的問題:
一、當lazy="true" fetch = "select" 的時候 , 這個時候是使用了延遲策略,開始只查詢出一端實體,多端的不會查詢,只有當用到的時候纔會發出sql語句去查詢 ;
二、當lazy="false" fetch = "select" 的時候 , 這個時候是使沒有用延遲策略,同時查詢出一端和多端,同時產生1+n條sql.
三、當lazy="true"/lazy="false" fetch = "join"的時候,本身認爲這個時候延遲已經沒有什麼用了,由於採用的是外鏈接查詢,同時把一端和多端都查詢出來了,延遲沒有起做用。


sql

Hibernate的fetch="join"和fetch="select" 的一點分析 fetch

fetch參數指定了關聯對象抓取的方式是select查詢仍是join查詢,select方式時先查詢返回要查詢的主體對象(列表),再根據關聯外鍵id,每個對象發一個select查詢,獲取關聯的對象,造成n+1次查詢;
而join方式,主體對象和關聯對象用一句外鍵關聯的sql同時查詢出來,不會造成屢次查詢。
若是你的關聯對象是延遲加載的,它固然不會去查詢關聯對象。
另外,在hql查詢中配置文件中設置的join方式是不起做用的(而在全部其餘查詢方式如get、criteria或再關聯獲取等等都是有效的),會使用select方式,除非你在hql中指定join fetch某個關聯對象。spa

 

fetch策略用於定義 get/load一個對象時,如何獲取非lazy的對象/集合。 這些參數在Query中無效。對象

fetch策略用於定義 get/load一個對象時,如何獲取非lazy的對象/集合。 這些參數在Query中無效。blog

 

查詢抓取(默認的)在N+1查詢的狀況下是很差的,所以咱們可能會要求在映射文檔中定義使用鏈接抓取:事務

 

<set name="permissions"
fetch="join">
<key column="userId"/>
<one-to-many class="Permission"/>
</set
<many-to-one name="mother" class="Cat" fetch="join"/>
在映射文檔中定義的抓取策略將會有產生如下影響:文檔

經過get()或load()方法取得數據。get

只有在關聯之間進行導航時,纔會隱式的取得數據(延遲抓取)。it

條件查詢io

在映射文檔中顯式的聲明 鏈接抓取作爲抓取策略並不會影響到隨後的HQL查詢。

一般狀況下,咱們並不使用映射文檔進行抓取策略的定製。更多的是,保持其默認值,而後在特定的事務中, 使用HQL的左鏈接抓取(left join fetch) 對其進行重載。這將通知 Hibernate在第一次查詢中使用外部關聯(outer join),直接獲得其關聯數據。 在條件查詢 API中,應該調用 setFetchMode(FetchMode.JOIN)語句。

其實這並不能說明hql可以按照配置文件設置的join進行抓取,這時 第二級:topic-->forum 的抓取其實已經和hql沒有關係了,由於前面已經產生了另外一個select方式的抓取語句。
而是對象的關聯獲取,假如查詢message時topic是設置爲延遲加載的,那麼在後面獲取message.topic時,如topic.forum不延遲加載,那麼topic-->forum會實現配置的join方式的抓取,這個顯然和hql查詢沒有關係。


原文地址:http://qinhanbin.iteye.com/blog/520038

 

        http://sun-gufeng-126-com.iteye.com/blog/629261

相關文章
相關標籤/搜索