觀點:對於n+1問題的理解。
一般而言說n+1意思是,無論在一對多還是多對一當查詢出n條資料之後,每條資料會關聯的查詢1次他的關聯物件,這就叫做n+1。
但是我的理解是,本來所有資訊可以一次性查詢出來,也就是簡單的連表查詢,但是hibernate會首先查詢1次得到當前物件,然後當前物件裡面的n個關聯物件會再次訪問資料庫n次,這就是1+n問題。
他們二者之間表達的意思其實是一樣的,只是描述這個問題的角度不同。不過我認為1+n更準確,因為以前我第一次看到n+1問題的時候就總是在想是不是查n然後多出一次,那其實是沒什麼影響的,後來才明白。
既然出現這個問題,肯定是要避免的,尤其是對於高併發的網際網路應用,這種現象是絕對不允許出現的。
hibernate給出了3中解決方案,不過我個人比較偏向於手動寫sql,也就是jdbc或者ibatis那種風格。因為這樣的sql是絕對可控的,只是在移植性方面不如hibernate。各有所長各有所短吧。
下面是3中解決方案:
1.延遲載入,當需要的時候才查詢,不需要就不查詢,但是感覺這種方式治標不治本,尤其是在那種報表統計查詢的時候更為明顯。
2.fetch="join",預設是fetch="select",這個其實說白了就是乙個做外連線,允許外來鍵為空的情況之下。
3.二級快取,第一次查詢之後存在記憶體中,後面的相同查詢就快了。但是有2個缺點:a.二級快取首先是有點浪費記憶體空間,如果多了的話浪費還比較嚴重,這是乙個不好的方面,當然這不是主要的,主要的問題在於,二級快取的特性決定的,那就是很少的增刪改才做二級快取,而對於普通的crud系統,其實不太適合。所以感覺也不是首選。
綜合來看,用外聯結的方式比較好,hibernate裡面貌似叫什麼迫切外聯結,不知道他究竟有多迫切,非得取個這樣的名字,不就是個關聯查詢嘛。
參考:
HIBERNATE的N 1查詢問題
在session的快取中存放的是相互關聯的物件圖。預設情況下,當hibernate從資料庫中載入customer物件時,會同時載入所有關聯的order物件。以customer和order類為例,假定orders表的customer id外來鍵允許為null,圖1列出了customers表和order...
hibernate中的n 1問題
前提 hibernate預設表與表的關聯方法是fetch select 不是fetch join 這都是為了懶載入而準備的。1 一對多 在1的這方,通過1條sql查詢得到了1個物件,由於關聯的存在 那麼又需要將這個物件關聯的集合取出,所以合集數量是n還要發出n條sql,於是本來的1條sql查詢變成了...
hibernate的n 1查詢問題
在 session 的快取中存放的是相互關聯的物件圖。預設情況下,當 hibernate 從資料庫中載入 customer 物件時,會同時載入所有關聯的 order 物件。以 customer 和order 類為例,假定 orders 表的customer id 外來鍵允許為 null,圖1 列出了...