国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費(fèi)電子書(shū)等14項(xiàng)超值服

開(kāi)通VIP
FetchMode解決Hibernate3中取得多層數(shù)據(jù)的所產(chǎn)生的n+1 selects問(wèn)題
FetchMode解決Hibernate3中取得多層數(shù)據(jù)的所產(chǎn)生的n+1 selects問(wèn)題
2009-06-01 10:17
其實(shí)這個(gè)問(wèn)題在Hibernate in Action中已經(jīng)有很多種解決辦法了。但我覺(jué)得其中最好的辦法是用Criteria的FetchMode來(lái)解決,但是Hibernate in Action中寫(xiě)的很不詳細(xì)。我昨晚試了好長(zhǎng)時(shí)間來(lái)的到答案。下面總結(jié)一下。
需求這樣的,我有四張表(one,two,three,four)從one一直外鍵關(guān)聯(lián)到four。結(jié)構(gòu)如下

現(xiàn)在在Session中得到One,并從One里一直取到Four里的內(nèi)容。如果簡(jiǎn)單的用Session.get來(lái)實(shí)現(xiàn)是這樣的。
One one = (One)session.get(One.class,new Integer(1));
         Iterator iterone
= one.getTwos().iterator();
        
while(iterone.hasNext()){
             Two two
= (Two) iterone.next();
             Iterator itertwo
= two.getThrees().iterator();
            
while(itertwo.hasNext()){
                 Three three
= (Three) itertwo.next();
                 three.getFours().size();                
             }
         }
這樣我在Session關(guān)閉后返回的One里是從One到Four的信息都有的。
然而這樣做所導(dǎo)致的結(jié)果是生成大量的SQL查詢,這是一個(gè)典型的n+1 Selects問(wèn)題。如果系統(tǒng)結(jié)構(gòu)層次多,符合條件的記錄多,那么Hibernate為你生成的SQL查詢將是難以接受的。
對(duì)于這個(gè)例子生成的SQL是這樣的
Hibernate: select one0_.c_one_id as c1_0_, one0_.c_one_text as c2_3_0_ from One one0_ where one0_.c_one_id=?
Hibernate: select twos0_.c_one_id as c2_1_, twos0_.c_two_id as c1_1_, twos0_.c_two_id as c1_0_, twos0_.c_one_id as c2_2_0_, twos0_.c_two_text as c3_2_0_ from Two twos0_ where twos0_.c_one_id=?
Hibernate: select threes0_.c_two_id as c2_1_, threes0_.c_three_id as c1_1_, threes0_.c_three_id as c1_0_, threes0_.c_two_id as c2_1_0_, threes0_.c_three_text as c3_1_0_ from Three threes0_ where threes0_.c_two_id=?
Hibernate: select fours0_.c_three_id as c2_1_, fours0_.c_four_id as c1_1_, fours0_.c_four_id as c1_0_, fours0_.c_three_id as c2_0_0_, fours0_.c_four_text as c3_0_0_ from Four fours0_ where fours0_.c_three_id=?
Hibernate: select fours0_.c_three_id as c2_1_, fours0_.c_four_id as c1_1_, fours0_.c_four_id as c1_0_, fours0_.c_three_id as c2_0_0_, fours0_.c_four_text as c3_0_0_ from Four fours0_ where fours0_.c_three_id=?
Hibernate: select threes0_.c_two_id as c2_1_, threes0_.c_three_id as c1_1_, threes0_.c_three_id as c1_0_, threes0_.c_two_id as c2_1_0_, threes0_.c_three_text as c3_1_0_ from Three threes0_ where threes0_.c_two_id=?
Hibernate: select fours0_.c_three_id as c2_1_, fours0_.c_four_id as c1_1_, fours0_.c_four_id as c1_0_, fours0_.c_three_id as c2_0_0_, fours0_.c_four_text as c3_0_0_ from Four fours0_ where fours0_.c_three_id=?
Hibernate: select fours0_.c_three_id as c2_1_, fours0_.c_four_id as c1_1_, fours0_.c_four_id as c1_0_, fours0_.c_three_id as c2_0_0_, fours0_.c_four_text as c3_0_0_ from Four fours0_ where fours0_.c_three_id=?
對(duì)于這樣的問(wèn)題,在沒(méi)有Hibernate以前我們一般都用jdbc來(lái)做,那樣的話我們其實(shí)用一個(gè)進(jìn)行3次join的sql語(yǔ)句就可以實(shí)現(xiàn),但是這樣解決也有問(wèn)題,就是返回的ResultSet中的數(shù)據(jù)非常多,而且雜亂,其實(shí)是從one到four平行排列的。對(duì)于這樣的結(jié)果集我們要把它手動(dòng)影射曾對(duì)象結(jié)構(gòu)也是一個(gè)很復(fù)雜的操作。
幸好Hibernate3可以為我們做這些事情(我再一次被Hibernate的強(qiáng)大所震撼)。
上面的實(shí)現(xiàn)可以用Criteria來(lái)實(shí)現(xiàn):
session = sessionFactory.openSession();
         Criteria criteria
= session.createCriteria(One.class);
         criteria.add(Expression.eq(
"COneId",new Integer(1)));
         one
= (One)criteria.setFetchMode("twos",FetchMode.JOIN).setFetchMode("twos.threes",FetchMode.JOIN).setFetchMode("twos.threes.fours",FetchMode.JOIN).uniqueResult();
         session.close();

這里的重點(diǎn)是這句話criteria.setFetchMode("twos",FetchMode.JOIN).setFetchMode("twos.threes",FetchMode.JOIN).setFetchMode("twos.threes.fours",FetchMode.JOIN).uniqueResult();
在用Criteria之前先設(shè)置FetchMode,應(yīng)為Criteria是動(dòng)態(tài)生成sql語(yǔ)句的,所以生成的sql就是一層層Join下去的。
setFetchMode(String,Mode)第一個(gè)參數(shù)是association path,用"."來(lái)表示路徑。這一點(diǎn)具體的例子很少,文檔也沒(méi)有寫(xiě)清楚。我也是試了很久才試出來(lái)的。
就這個(gè)例子來(lái)所把因?yàn)槿〉赖谒膶?,所以要進(jìn)行三次setFetchMode
第一次的路徑是twos,一位one中有two的Set。這個(gè)具體要更具h(yuǎn)bm.xml的配置來(lái)定。
第二個(gè)路徑就是twos.threes
第三個(gè)就是twos.threes.fours
一次類推,一層層增加的。
這樣做法最終生成的SQL是這樣的:
Hibernate: select this_.c_one_id as c1_3_, this_.c_one_text as c2_3_3_, twos2_.c_one_id as c2_5_, twos2_.c_two_id as c1_5_, twos2_.c_two_id as c1_0_, twos2_.c_one_id as c2_2_0_, twos2_.c_two_text as c3_2_0_, threes3_.c_two_id as c2_6_, threes3_.c_three_id as c1_6_, threes3_.c_three_id as c1_1_, threes3_.c_two_id as c2_1_1_, threes3_.c_three_text as c3_1_1_, fours4_.c_three_id as c2_7_, fours4_.c_four_id as c1_7_, fours4_.c_four_id as c1_2_, fours4_.c_three_id as c2_0_2_, fours4_.c_four_text as c3_0_2_ from One this_ left outer join Two twos2_ on this_.c_one_id=twos2_.c_one_id left outer join Three threes3_ on twos2_.c_two_id=threes3_.c_two_id left outer join Four fours4_ on threes3_.c_three_id=fours4_.c_three_id where this_.c_one_id=?
雖然很長(zhǎng)但是只有一條SQL語(yǔ)句。性能要好很多。Hibernate的強(qiáng)大之處是它會(huì)把返回的ResultSet自動(dòng)影射到你的對(duì)象模型里面去。這就為我們省了很多事。

看來(lái)Hibernate真是一個(gè)耐人尋味的Framework啊


本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)
打開(kāi)APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
Hibernate Criteria 查詢---使用原生sql語(yǔ)句設(shè)定查詢條件
Hibernate QBE 復(fù)合查詢問(wèn)題
Hibernate: Criteria vs. HQL
Hibernate3.2 .1參考文檔
php5 操作MYSQL的類
hibernate集合映射inverse和cascade詳解
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服