<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    隨筆-59  評(píng)論-31  文章-0  trackbacks-0

    在Session的緩存中存放的是相互關(guān)聯(lián)的對(duì)象圖。默認(rèn)情況下,當(dāng)Hibernate從數(shù)據(jù)庫(kù)中加載Customer對(duì)象時(shí),會(huì)同時(shí)加載所有關(guān)聯(lián)的 Order對(duì)象。以Customer和Order類為例,假定ORDERS表的CUSTOMER_ID外鍵允許為null

    以下Session的find()方法用于到數(shù)據(jù)庫(kù)中檢索所有的Customer對(duì)象: 

    List customerLists=session.find("from Customer as c"); 

    運(yùn)行以上find()方法時(shí),Hibernate將先查詢CUSTOMERS表中所有的記錄,然后根據(jù)每條記錄的ID,到ORDERS表中查詢有參照關(guān)系的記錄,Hibernate將依次執(zhí)行以下select語句: 

    select * from CUSTOMERS; 
    select * from ORDERS where CUSTOMER_ID=1; 
    select * from ORDERS where CUSTOMER_ID=2; 
    select * from ORDERS where CUSTOMER_ID=3; 
    select * from ORDERS where CUSTOMER_ID=4; 

    通過以上5條select語句,Hibernate最后加載了4個(gè)Customer對(duì)象和5個(gè)Order對(duì)象,在內(nèi)存中形成了一幅關(guān)聯(lián)的對(duì)象圖.


    Hibernate在檢索與Customer關(guān)聯(lián)的Order對(duì)象時(shí),使用了默認(rèn)的立即檢索策略。這種檢索策略存在兩大不足: 

    (1) select語句的數(shù)目太多,需要頻繁的訪問數(shù)據(jù)庫(kù),會(huì)影響檢索性能。如果需要查詢n個(gè)Customer對(duì)象,那么必須執(zhí)行n+1次select查詢語 句。這就是經(jīng)典的n+1次select查詢問題。這種檢索策略沒有利用SQL的連接查詢功能,例如以上5條select語句完全可以通過以下1條 select語句來完成: 

    select * from CUSTOMERS left outer join ORDERS 
    on CUSTOMERS.ID=ORDERS.CUSTOMER_ID 

    以上select語句使用了SQL的左外連接查詢功能,能夠在一條select語句中查詢出CUSTOMERS表的所有記錄,以及匹配的ORDERS表的記錄。 

    (2)在應(yīng)用邏輯只需要訪問Customer對(duì)象,而不需要訪問Order對(duì)象的場(chǎng)合,加載Order對(duì)象完全是多余的操作,這些多余的Order對(duì)象白白浪費(fèi)了許多內(nèi)存空間。 
    為了解決以上問題,Hibernate提供了其他兩種檢索策略:延遲檢索策略和迫切左外連接檢索策略。延遲檢索策略能避免多余加載應(yīng)用程序不需要訪問的關(guān)聯(lián)對(duì)象,迫切左外連接檢索策略則充分利用了SQL的外連接查詢功能,能夠減少select語句的數(shù)目。


    對(duì)數(shù)據(jù)庫(kù)訪問還是必須考慮性能問題的, 在設(shè)定了1 對(duì)多這種關(guān)系之后, 查詢就會(huì)出現(xiàn)傳說中的n +1 問題。 
    1 )1 對(duì)多,在1 方,查找得到了n 個(gè)對(duì)象, 那么又需要將n 個(gè)對(duì)象關(guān)聯(lián)的集合取出,于是本來的一條sql查詢變成了n +1 條 
    2)多對(duì)1 ,在多方,查詢得到了m個(gè)對(duì)象,那么也會(huì)將m個(gè)對(duì)象對(duì)應(yīng)的1 方的對(duì)象取出, 也變成了m+1

    怎么解決n +1 問題? 
    1 )lazy=true, hibernate3開始已經(jīng)默認(rèn)是lazy=true了;lazy=true時(shí)不會(huì)立刻查詢關(guān)聯(lián)對(duì)象,只有當(dāng)需要關(guān)聯(lián)對(duì)象(訪問其屬性,非id字段)時(shí)才會(huì)發(fā)生查詢動(dòng)作。 

    2)二級(jí)緩存, 在對(duì)象更新,刪除,添加相對(duì)于查詢要少得多時(shí), 二級(jí)緩存的應(yīng)用將不怕n +1 問題,因?yàn)榧词沟谝淮尾樵兒苈?,之后直接緩存命中也是很快的?nbsp;
    不同解決方法,不同的思路,第二條卻剛好又利用了n +1 。

    3) 當(dāng)然你也可以設(shè)定fetch=join(annotation : @ManyToOne() @Fetch(FetchMode.JOIN))

    posted on 2012-01-30 14:20 RoyPayne 閱讀(10908) 評(píng)論(1)  編輯  收藏 所屬分類: SSH

    評(píng)論:
    # re: Hibernate n+1問題 2012-12-25 18:11 | qinxike
    現(xiàn)在問題是加了fetch會(huì)報(bào)錯(cuò)!除了fetch,沒有其他辦法了嗎?  回復(fù)  更多評(píng)論
      

    只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 一区视频免费观看| 激情97综合亚洲色婷婷五| 国产啪精品视频网站免费尤物| 亚洲综合色丁香婷婷六月图片| 西西人体44rt高清亚洲| 亚洲午夜无码片在线观看影院猛| 成人午夜大片免费7777| 中文字幕在线免费| 精品亚洲永久免费精品| 一进一出60分钟免费视频| 亚洲Av永久无码精品黑人| 亚洲av日韩av无码av| 亚洲制服中文字幕第一区| 亚洲精品~无码抽插| 亚洲熟伦熟女新五十路熟妇| 日本免费v片一二三区| 好男人www免费高清视频在线| 亚洲一区二区在线免费观看| 成在人线av无码免费高潮喷水| 成人一级免费视频| 免费夜色污私人影院网站电影| 亚洲欧美乱色情图片| 亚洲日韩一区精品射精| 亚洲人成综合网站7777香蕉| 亚洲制服丝袜一区二区三区| 91在线亚洲精品专区| 亚洲一区二区三区夜色| 亚洲国产精品高清久久久| 国产亚洲人成网站观看| 在线观看午夜亚洲一区| 亚洲精品无码精品mV在线观看| 亚洲无线码在线一区观看| 国产亚洲?V无码?V男人的天堂| 亚洲中文无韩国r级电影| 国产成人亚洲影院在线观看| 亚洲国产精品综合久久网络| 亚洲精品久久久www | 亚洲综合激情视频| 亚洲网站免费观看| 久久精品亚洲AV久久久无码 | 91成人在线免费观看|