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

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

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

    one-to-one的效率問(wèn)題,用one-to-many來(lái)替代?

             由于最近在把以前的一個(gè)設(shè)計(jì)移到hibernate上來(lái),所以需要用到one-to-one,因?yàn)樵谝郧暗脑O(shè)計(jì)中需要用到在一個(gè)主表中對(duì)于多個(gè)子表的主鍵關(guān)聯(lián),所以一開(kāi)始就想到了one-to-one的應(yīng)用,覺(jué)得這樣解決不但不會(huì)引起以前數(shù)據(jù)設(shè)計(jì)的改變,也能夠很好的利用hibernate所帶來(lái)的OR優(yōu)勢(shì),可是當(dāng)實(shí)際使用的時(shí)候發(fā)現(xiàn),在插入數(shù)據(jù)的時(shí)候可以有選擇的在任意子表中進(jìn)行插入,所有的結(jié)果都在原來(lái)的預(yù)期之中,但是在查詢的時(shí)候,比如說(shuō)只查詢主表中的內(nèi)容

             From tableMain

    僅僅執(zhí)行看起來(lái)十分簡(jiǎn)單的一條語(yǔ)句,你所期望的是他緊緊查詢T_MAIN這張主表,可是結(jié)果確實(shí)hibernate通過(guò)多個(gè)外連接將所有的子表一口氣的全部查詢出來(lái)

             select * from t_main main outer join t_sub1 sub1 on main.id = sub1.id outer join t_sub2 sub2 on main.id = sub2.id...

     如此的效率絕對(duì)讓你頭痛不已,不僅如此,如果你通過(guò)首先獲得子表t_sub1的某個(gè)主鍵ID,然后通過(guò)這個(gè)主鍵查詢出子表對(duì)象,在關(guān)聯(lián)至住表,同樣的情況又會(huì)發(fā)生,又會(huì)生成類似的SQL語(yǔ)句,這樣一來(lái)看來(lái)對(duì)于這個(gè)設(shè)計(jì)應(yīng)用one-to-one本身就是一種錯(cuò)誤,是這樣嗎?

             或許有人認(rèn)為我們?cè)诿總€(gè)one-to-one中加入lazy="true"這個(gè)屬性會(huì)杜絕上述情況的發(fā)生,經(jīng)過(guò)筆者的證實(shí)即便你加入了lazy="true",也不會(huì)帶來(lái)任何的改變;又或者在hibernate.config中加入fetch depth屬性以及在每個(gè)關(guān)聯(lián)中設(shè)置outer-join="false",這些都不會(huì)引起本質(zhì)上的變化,加入outer-join="false"其實(shí)結(jié)果只是將原有的outer join語(yǔ)句改變成多條sql語(yǔ)句而已,并沒(méi)發(fā)生什么本質(zhì)變化,反而效率更低了。

             該怎么辦呢?我們先仔細(xì)研究一下one-to-one的概念,one to one代表一對(duì)一,在一般的模型中很少會(huì)遇到one-to-one這種概念,因?yàn)樗謴?qiáng)調(diào)一對(duì)一的概念,就好比一個(gè)人他只有一個(gè)身體和一個(gè)頭而已,頭和身體是十分好的例子,因?yàn)橛猩眢w必定只有一個(gè)頭,而且說(shuō)到了身體必定要說(shuō)頭,就好像看了某個(gè)女孩的身材必定想知道她的長(zhǎng)相如何(-_-),所以在這時(shí)我們使用one-to-one,因?yàn)檫@種一對(duì)一的關(guān)系是很強(qiáng)的,而且從對(duì)象中取得body必定會(huì)取得他所關(guān)聯(lián)的head,這樣的情況下使用outer-join是十分方便和有效率的,因?yàn)樗褂昧薿uter join查詢從而避免了兩條到數(shù)據(jù)庫(kù)的查詢語(yǔ)句,而且在這種情況下也只需要在body_hbm.xml中設(shè)置一個(gè)one-to-one即可,所以在這種確實(shí)是一對(duì)一而且在主表中一對(duì)一的關(guān)聯(lián)個(gè)數(shù)(即主表中one-to-one標(biāo)簽)十分少的情況下,使用one-to-one是一種很不錯(cuò)的解決辦法。

             如果一個(gè)主表會(huì)對(duì)多個(gè)子表都進(jìn)行one-to-one關(guān)聯(lián)呢,就像我們一開(kāi)始遇到的這種情況,比如你不僅僅只想了解那個(gè)你中意的女孩的身材和臉蛋,而且還想知道他的學(xué)歷,身世等等一切,在這種情況下,如果我們都是用多個(gè)one-to-one在主表中的話,那情況正如我們一開(kāi)始看見(jiàn)的,是十分可怕的,該怎么做呢?不妨考慮一下使用one-to-many,什么,many?一開(kāi)始聽(tīng)到many這個(gè)詞的時(shí)候,我也覺(jué)得挺驚訝的這明明是多個(gè)一對(duì)一的關(guān)聯(lián)為什么要用到many呢?其實(shí)many并沒(méi)有一定要說(shuō)是大于一的,你就只在它的many中存在一個(gè)關(guān)聯(lián)它有能乃你何呢?如果用到many的話,我們就需要改動(dòng)數(shù)據(jù)表的設(shè)計(jì)了,在每個(gè)有關(guān)連的子表中加入一列main_id代表主表中該記錄的主鍵子段值,只需要這樣子改動(dòng)就可以了,這樣所帶來(lái)的效果絕對(duì)是值得你這樣做的,然后我們就按照以往的one-to-many來(lái)設(shè)計(jì)就好了

             在body.hbm.xml加入(一到head的關(guān)聯(lián)舉例,其他的關(guān)聯(lián)按照這樣的格式添加即可)
             <set name="head" inverse="true" lazy="true" cascade="all-delete-orphan">
                <key column="ID0000"/>
                <one-to-many class="com.xx.Head"/>
              </set>

             在head.hbm.xml加入
             <many-to-one name="body" column="ID0000" class="com.xx.Body" not-null="true"/>

             行了,經(jīng)過(guò)上面的改動(dòng)我們就擺脫了查詢時(shí)多個(gè)outer-join的困擾,只在需要的時(shí)候才對(duì)子表進(jìn)行查詢,因?yàn)樵O(shè)置了lazy="true",所以一切的一切都在我們的預(yù)料之中,我們?nèi)绻M@得body的話hibernate絕對(duì)不會(huì)把它的head 也查詢出來(lái),節(jié)省了查詢是所需要的負(fù)擔(dān),除非到了我們十分需要head的情況才會(huì)進(jìn)行關(guān)聯(lián)查詢,獲得所需要的head結(jié)果。

             所以由此看來(lái)在one-to-one這種一對(duì)一的關(guān)系不是很強(qiáng)的情況下,或者是在一張表中存在多個(gè)one-to-one的情況下,使用one-to-many來(lái)代替one-to-one不失為一種不錯(cuò)的做法,當(dāng)然更重要的良好的數(shù)據(jù)庫(kù)設(shè)計(jì),hibernate畢竟只是末,千萬(wàn)不要本末倒置
          

    posted on 2005-03-30 13:26 Find it, try it, experience it 閱讀(10387) 評(píng)論(8)  編輯  收藏

    評(píng)論

    # re: one-to-one的效率問(wèn)題,用one-to-many來(lái)替代? 2005-06-30 14:28 dean

    You can also use join to avoid modifying the existing database schema (but will add an associating table):

    <class name="Person">
    <id name="id" column="personId">
    <generator class="native"/>
    </id>
    <join table="PersonAddress" optional="true">
    <key column="personId" unique="true"/>
    <many-to-one name="address" column="addressId"
    not-null="true"/>
    </join>
    </class>
    <class name="Address">
    <id name="id" column="addressId">
    <generator class="native"/>
    </id>
    </class>

    create table Person ( personId bigint not null primary key )
    create table PersonAddress ( personId bigint not null primary key, addressId bigint not null )
    create table Address ( addressId bigint not null primary key )  回復(fù)  更多評(píng)論   

    # re: one-to-one的效率問(wèn)題,用one-to-many來(lái)替代? 2005-07-02 22:05 ramon

    if there is sth u want to say, speak it in Chinese next time please  回復(fù)  更多評(píng)論   

    # re: one-to-one的效率問(wèn)題,用one-to-many來(lái)替代? 2005-08-30 21:57 Roberto Sweater

    一個(gè)月前Gavin King 在hibernate3.1 beta2 中進(jìn)行了修改
    Created: 23/Jul/05 06:24 PM Updated: 30/Jul/05 12:11 AM

    http://opensource2.atlassian.com/projects/hibernate/browse/HHH-786?page=all

    sswt163@gmail.com
      回復(fù)  更多評(píng)論   

    # one-to-one的效率問(wèn)題,用one-to-many來(lái)替代? (轉(zhuǎn)自http://m.tkk7.com/ramon/)[TrackBack] 2005-11-01 12:10 insiderys

    如同作者,剛好想用一個(gè)one-to-one來(lái)實(shí)現(xiàn)自己的持久化類,查了查,還有這樣的技巧,值得學(xué)習(xí)~~
    [引用提示]insiderys引用了該文章, 地址: http://blog.csdn.net/insiderys/archive/2005/11/01/520410.aspx  回復(fù)  更多評(píng)論   

    # re: one-to-one的效率問(wèn)題,用one-to-many來(lái)替代? 2008-01-11 09:46 kuan

    如果設(shè)置成<set>,那不是要在VO里修改原來(lái)一對(duì)一的那種映射方式為Set?  回復(fù)  更多評(píng)論   

    # re: one-to-one的效率問(wèn)題,用one-to-many來(lái)替代? 2008-01-13 20:23 Ramon

    @kuan
    老了,那是我對(duì)HIB2.2的一點(diǎn)理解了,現(xiàn)在3.X系列早已經(jīng)在DEFAULT的情況下是lazy-loading了:)

    Yours,
    Ramon  回復(fù)  更多評(píng)論   

    # re: one-to-one的效率問(wèn)題,用one-to-many來(lái)替代?[未登錄](méi) 2008-10-06 22:31 bobo

    胡扯(one-to-many跟many-to-one搭配只會(huì)更差),只用一個(gè)many-to-one就可以  回復(fù)  更多評(píng)論   

    # re: one-to-one的效率問(wèn)題,用one-to-many來(lái)替代? 2008-10-07 09:30 Ramon

    樓上傻X,請(qǐng)看看我是對(duì)hib2.2的認(rèn)識(shí)...別在這里不懂裝懂  回復(fù)  更多評(píng)論   


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


    網(wǎng)站導(dǎo)航:
     
    <2008年10月>
    2829301234
    567891011
    12131415161718
    19202122232425
    2627282930311
    2345678

    導(dǎo)航

    統(tǒng)計(jì)

    公告

    If there is any question you have, please don't hesitate, let me know ASAP, you can find me at kenees@gmail.com or QQ: 9808873, hope to make friends with you ;)

    常用鏈接

    留言簿(1)

    隨筆檔案

    文章檔案

    搜索

    積分與排名

    最新評(píng)論

    閱讀排行榜

    評(píng)論排行榜

    主站蜘蛛池模板: 91精品国产免费入口| 啦啦啦在线免费视频| 久久美女网站免费| 啦啦啦中文在线观看电视剧免费版 | 中文字幕亚洲激情| 亚洲欧洲另类春色校园小说| 免费国产高清毛不卡片基地| 四虎影视成人永久免费观看视频| 国产美女a做受大片免费| 色播亚洲视频在线观看| 日韩精品视频在线观看免费| 亚洲精品偷拍视频免费观看 | 色www永久免费视频| 亚洲成人在线电影| 一区二区视频免费观看| 夜夜爽免费888视频| 亚洲hairy多毛pics大全| 18禁美女裸体免费网站| 亚洲va久久久噜噜噜久久| 在线播放免费人成视频网站| 麻豆国产人免费人成免费视频| 99热亚洲色精品国产88| 国产精品久久永久免费| 亚洲国产精品久久久久久| 9久久免费国产精品特黄| 免费a级毛片18以上观看精品| 亚洲综合校园春色| 全部免费国产潢色一级| 亚洲七久久之综合七久久| 青青青国产在线观看免费网站| 亚洲国产精品久久久久网站 | 精品熟女少妇aⅴ免费久久| 亚洲第一中文字幕| 免费看美女让人桶尿口| 999zyz**站免费毛片| 色噜噜AV亚洲色一区二区| www.av在线免费观看| 在线不卡免费视频| 久久WWW免费人成—看片| 亚洲人成电影在线观看网| 国产在线观看片a免费观看|