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

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

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

    風(fēng)行天下

    JAVA太極
    posts - 4, comments - 10, trackbacks - 0, articles - 55
      BlogJava :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

    Hibernate 的一些研究

    Posted on 2005-07-21 16:50 風(fēng)太少 閱讀(194) 評(píng)論(0)  編輯  收藏
             由于最近在把以前的一個(gè)設(shè)計(jì)移到hibernate上來(lái),所以需要用到one-to-one,因?yàn)樵谝郧暗脑O(shè)計(jì)中需要用到在一個(gè)主表中對(duì)于多個(gè)子表的主鍵關(guān)聯(lián),所以一開始就想到了one-to-one的應(yīng)用,覺得這樣解決不但不會(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)呢,就像我們一開始遇到的這種情況,比如你不僅僅只想了解那個(gè)你中意的女孩的身材和臉蛋,而且還想知道他的學(xué)歷,身世等等一切,在這種情況下,如果我們都是用多個(gè)one-to-one在主表中的話,那情況正如我們一開始看見的,是十分可怕的,該怎么做呢?不妨考慮一下使用one-to-many,什么,many?一開始聽到many這個(gè)詞的時(shí)候,我也覺得挺驚訝的這明明是多個(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 @ 2005-03-30 13:26 一個(gè)人的日子,我獨(dú)來(lái)獨(dú)往 閱讀(217) | 評(píng)論 (2)編輯 收藏

          one-to-one在hibernate中可以用來(lái)作為兩張表之間的主鍵關(guān)聯(lián),這也是hibernate中主鍵關(guān)聯(lián)的一種用法,這樣在一張表中的ID,在生成另外一張表的同時(shí)回自動(dòng)插入到相應(yīng)的ID字段中去,相應(yīng)的XML文件設(shè)置比較簡(jiǎn)單,舉例如下:

        <!-- 建立一對(duì)一的到Address的映射,這個(gè)是寫在User的XML配置文件中的 -->
        <!-- 相應(yīng)的User bean(PO)中也要添加屬性 com.xx.Address  address-->
        <one-to-one name="address" cascade="all" class="com.xx.Address"/>
       
       <!-- cascade的屬性設(shè)置不再重復(fù)了,可以查看hibernate文檔 -->

        <!-- 建立一對(duì)一的到User的映射,這個(gè)是寫在Address的XML配置文件中的 -->
        <!-- 相應(yīng)的Address bean(PO)中也要添加屬性 com.xx.User user--> -->
        <one-to-one name="user" class="com.xx.User" constrained="true"/>

          為了在Address中使用User中的主鍵ID值,我們需要設(shè)置Address中的主鍵生成規(guī)則,如下所示,采用foreign關(guān)鍵字

       <id column="ID" name="id" type="long" unsaved-value="0">
          <generator class="foreign">
            <param name="property">user</param> 
          </generator>
       </id>


          這里需要注意的是property的屬性值必須與上面到User的映射所填寫的name屬性值一致,這樣就完成了one-to-one的映射關(guān)系。

    上面的過(guò)程都很簡(jiǎn)單,下面我來(lái)說(shuō)說(shuō)這里需要注意的地方:

      1.   在設(shè)置屬性ID的時(shí)候必須注意字段的長(zhǎng)度,如筆者這樣使用oracle的sequence來(lái)生成ID,其長(zhǎng)度有14位之長(zhǎng),則應(yīng)選擇hibernate類型long,對(duì)應(yīng)的實(shí)體中應(yīng)選擇Long,這樣不會(huì)出現(xiàn)溢出的情況。


      2.   在測(cè)試的時(shí)候必須要注意這兩張表之間因?yàn)橐呀?jīng)存在了一對(duì)一的關(guān)系,所以我們不能只寫
             user.setAddress(address);
             而忽略了
             address.setUser(user);
             這樣在做插入的時(shí)候會(huì)報(bào)出attempted to assign id from null one-to-one property: address的錯(cuò)誤,這一點(diǎn)初學(xué)者會(huì)經(jīng)常犯,筆者也是其中之一。


     3.   如果不寫cascade="all"或者寫成cascade="none"的話,即使你寫了
             user.setAddress(address);
             address.setUser(user);
           也不會(huì)發(fā)生任何事情,只有user會(huì)被存儲(chǔ)。

    以上是一些筆者經(jīng)歷的小經(jīng)驗(yàn),如果有不對(duì)的地方歡迎指正。

    posted @ 2005-03-23 17:27 一個(gè)人的日子,我獨(dú)來(lái)獨(dú)往 閱讀(437) | 評(píng)論 (5)編輯 收藏

          在很多情況下,我們使用Hibernate在已經(jīng)建立好數(shù)據(jù)庫(kù)的基礎(chǔ)上。在oracle中,如果已經(jīng)建立好的數(shù)據(jù)庫(kù)中使用了sequence,則可以按照下面的步驟把它引入到Hibernate中:
       
       1、在oracle 首先創(chuàng)建sequence

          
    create sequence seq_id
          minvalue 1
          start with 1
          increment by 1
          cache 20;

       2.在你的hbm.xml中的配置
       
         <id column="ID0000" name="id" type="integer">
             <generator class="sequence">
                  <param name="sequence">seq_id</param>
             </generator>
         </id>


       這樣再插入數(shù)據(jù)的時(shí)候,Hibernate回自動(dòng)生成如下語(yǔ)句:
       
       hibernate: select seq_id.nextval from dual

       hibernate:  insert into YXJK.T_YXJK_WHRYTXL (XM0000, ZW0000, LXDH00, SJHM00, DZYJ00,   
                        IP0000,     ID0000) values (?, ?, ?, ?, ?, ?, ?)

       自動(dòng)生成下一個(gè)序列值,然后將對(duì)象插入表中。
       在使用的時(shí)候需要注意,Hibernate對(duì)于sequence的主鍵的要求是一定要是shor,long,或者integer

    posted @ 2005-03-23 10:30 一個(gè)人的日子,我獨(dú)來(lái)獨(dú)往 閱讀(313) | 評(píng)論 (0)編輯 收藏

    在做具有MVC結(jié)構(gòu)的B/S程序時(shí),怎樣將這三層隔離開是十分關(guān)鍵的,一般用DAO封裝Hibernate來(lái)獲得對(duì)數(shù)據(jù)庫(kù)的具體操作,在這里我們可以為每一個(gè)需要建立O-R MAPPING的對(duì)象(通過(guò)Hibernate實(shí)現(xiàn)OR映射)實(shí)現(xiàn)一個(gè)DAO,然后通過(guò)這個(gè)DAO來(lái)獲得具體的數(shù)據(jù)庫(kù)操作,用DAO的好處是我們可以把對(duì)一個(gè)對(duì)象的操作集中在同一個(gè)DAO中,便于管理,另外向上層只提供了接口屏蔽了底層對(duì)數(shù)據(jù)庫(kù)的操作,通過(guò)hibernate,我們向上層直接提供建立了O-R MAPPING的OBJECT;同時(shí)在領(lǐng)域模型這一層,也就是M這一層,我們將一些業(yè)務(wù)邏輯(business logic)封裝進(jìn)來(lái),這里所指的M這一層通常也就是我們?cè)贖ibernate中所用到的plain objectS,就是用來(lái)建立O-R MAPPING所需要用到的與表對(duì)應(yīng)的OBJECTs,一般的領(lǐng)域模型都是由這些plain objectS構(gòu)成;這樣我們?cè)诳刂茖右簿褪荂這一層只需要初始化DAO打開到持久層的通路,然后調(diào)用一些簡(jiǎn)單的方法執(zhí)行業(yè)務(wù)邏輯,請(qǐng)注意這時(shí)候我們的業(yè)務(wù)邏輯已經(jīng)被封裝在領(lǐng)域模型這一層中了,這樣我們每一層都是相互獨(dú)立的,控制層C和展現(xiàn)層V都不和持久層所提供的接口有關(guān)系

    posted @ 2005-03-17 23:14 一個(gè)人的日子,我獨(dú)來(lái)獨(dú)往 閱讀(123) | 評(píng)論 (0)編輯 收藏

    今天的主要收獲是發(fā)現(xiàn)通過(guò)在servlet的Filter中實(shí)現(xiàn)session.begin(),session.close(),session.beginTransaction()以及transaction.commit()是一個(gè)不錯(cuò)的選擇servlet1.gif
    如上圖這樣,在從服務(wù)器端返回到客戶端的時(shí)候,也就是在轉(zhuǎn)向到最終頁(yè)面的時(shí)候,由Filter實(shí)現(xiàn)關(guān)閉session和transaction,是一個(gè)很好的實(shí)現(xiàn)方法


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


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 日本免费一区二区久久人人澡 | 一级一黄在线观看视频免费| 亚洲成AV人在线观看网址| 久久99精品免费一区二区| 久久综合亚洲色HEZYO社区| 在线a人片天堂免费观看高清| 一级毛片视频免费| 少妇中文字幕乱码亚洲影视| 国产aa免费视频| 毛片无码免费无码播放| 真正全免费视频a毛片| 亚洲av色福利天堂| 四虎影视永久免费观看地址| 一级毛片免费观看不卡视频| 亚洲AV无码一区二区乱子仑 | 亚洲精品在线观看视频| 热久久精品免费视频| 久久国产精品成人免费| 99亚洲乱人伦aⅴ精品| 亚洲欧洲国产经精品香蕉网| 亚洲M码 欧洲S码SSS222| 2019中文字幕在线电影免费| www.av在线免费观看| 亚洲成人福利网站| 亚洲午夜国产精品无码老牛影视 | 亚洲黄片手机免费观看| 中文字幕亚洲情99在线| 亚洲激情在线观看| 亚洲午夜国产精品无码 | 亚洲AV网站在线观看| 57PAO成人国产永久免费视频 | 德国女人一级毛片免费| 久久综合九色综合97免费下载| 国产亚洲精品美女久久久久| 久久精品国产亚洲av麻豆图片| 国产AV无码专区亚洲精品| 四虎永久在线精品视频免费观看| 99久久国产热无码精品免费| 日韩精品内射视频免费观看| 中文字幕在线免费视频| 亚洲国产成人AV网站|