thinking

          one platform thousands thinking

          many-to-one/one-to-many/many-to-many關(guān)系映射

          本文的內(nèi)容:
          介紹NH如何處理對(duì)象間many-to-one,one-to-many和many-to-many的雙向映射關(guān)系(本文主要介紹了映射文件,對(duì)于類的生成可以跟據(jù)前兩篇描述的方法生成);

          經(jīng)驗(yàn)教訓(xùn):

          相關(guān)類圖:(下面的類圖包含一對(duì)一,多對(duì)一,一對(duì)多和多對(duì)多)
          many-to-one:描 述多對(duì)一的一種數(shù)據(jù)模型,它指定many一方是不能獨(dú)立存在的,我個(gè)人認(rèn)為many-to-one是NHB中保證數(shù)據(jù)有效性的最有用的一種映射,通過使用 many-to-one能有效的防治孤兒記錄被寫入到數(shù)據(jù)表中。在本文描述的例子中,Student類和Classes類之間是多對(duì)一關(guān)系.

          通過many-to-one元素,可以定義一種常見的與另一個(gè)持久化類的關(guān)聯(lián)。這種關(guān)系模型是多對(duì)一關(guān)聯(lián)。(實(shí)際上是一個(gè)對(duì)象引用。)在映射文件中用many-to-one標(biāo)簽描述此種關(guān)系.
          <many-to-one
                  
          name="propertyName"(1)
                  column
          ="column_name"(2)
                  class
          ="ClassName"(3)
                  cascade
          ="all|none|save-update|delete"(4)
                  outer-join
          ="true|false|auto"(5)
                  update
          ="true|false"(6)
                  insert
          ="true|false"(7)
                  property-ref
          ="propertyNameFromAssociatedClass" (8)
                  access
          ="field|property|ClassName"(9)
                  unique
          ="true|false" (10)
          />

          1.name:屬性名。指出many一方的類用哪個(gè)屬性和one一方的類關(guān)聯(lián).
          2.column:字段名(可選).指出many一方的類對(duì)應(yīng)的數(shù)據(jù)表用哪個(gè)列和one一方的類對(duì)應(yīng)的數(shù)據(jù)表關(guān)聯(lián)(兩表之間存在外鍵關(guān)聯(lián));
          3.class:關(guān)聯(lián)的類的名字(可選 - 默認(rèn)是通過反射得到屬性類型);
          4.cascade:指明哪些操作會(huì)從父對(duì)象級(jí)聯(lián)到關(guān)聯(lián)的對(duì)象(可選).cascade屬性允許下列值:: all, save-update, delete, none. 設(shè)置除了none以外的其它值會(huì)傳播特定的操作到關(guān)聯(lián)的(子)對(duì)象中。
          5.outer-join:當(dāng)設(shè)置hibernate.use_outer_join的時(shí)候,對(duì)這個(gè)關(guān)聯(lián)允許外連接抓取(可選 - 默認(rèn)為 auto).outer-join參數(shù)允許下列三個(gè)不同值: auto(使用外連接抓取關(guān)聯(lián)(對(duì)象),如果被關(guān)聯(lián)的對(duì)象沒有代理(proxy) ),true(一直使用外連接來抓取關(guān)聯(lián)),false(永遠(yuǎn)不使用外連接來抓取關(guān)聯(lián));
          6.update,insert:指定對(duì)應(yīng)的字段是否在用于UPDATE 和/或 INSERT的SQL語句中包含。如果二者都是false,則這是一個(gè)純粹的“外源性(derived)”關(guān)聯(lián),它的值是通過映射到同一個(gè)(或多個(gè))字段的某些其他屬性得到的,或者通過trigger(除法器),或者是其他程序(可選 - 默認(rèn)為 true
          7.property- ref:指定關(guān)聯(lián)類的一個(gè)屬性,這個(gè)屬性將會(huì)和本外鍵相對(duì)應(yīng)。如果沒有指定,會(huì)使用對(duì)方關(guān)聯(lián)類的主鍵(可選).property-ref屬性只應(yīng)該用來對(duì) 付老舊的數(shù)據(jù)庫(kù)系統(tǒng),可能出現(xiàn)外鍵指向?qū)Ψ疥P(guān)聯(lián)表的是個(gè)非主鍵字段(但是應(yīng)該是一個(gè)惟一關(guān)鍵字)的情況。這是一種十分丑陋的關(guān)系模型。比如說,假設(shè) Product類有一個(gè)惟一的序列號(hào),它并不是主鍵;
          8.a(chǎn)ccess:NHibernate 用來訪問屬性的策略(可選 - 默認(rèn)為property
          9.unique:允許產(chǎn)生外鍵列唯一約束的數(shù)據(jù)庫(kù)定義語言(DDL)(可選)

          那么關(guān)于Student的映射可能是:

          <many-to-one name="Classes" column="cID" unique ="true"/>

          只要在原Student.hbm.xml映射文件中添加many-to-one標(biāo)簽就可以了.

          對(duì)于Sturent類得添加一個(gè)屬性Classes:Classes

          one-to-many:
          一對(duì)多也是一種常見的數(shù)據(jù)模型,在按范式設(shè)計(jì)的數(shù)據(jù)庫(kù)中隨處可見。在NHB中通過one-to-many可以非常方便的處理這種模型,同時(shí)NHB還提供了級(jí)聯(lián)更新和刪除的功能,以保證數(shù)據(jù)完整性。在本文描述的例子中,Classes類和Student類是一對(duì)多的關(guān)系.

          Classes類的映射文件:Classes.hbm.xml

          <?xml version="1.0" encoding="utf-8" ?>
          <hibernate-mapping xmlns="urn:nhibernate-mapping-2.0">
            
          <class name="NHibernateTest.Classes,NHibernateTest" table="Classes">
              
          <id name="ClassesID" column="ID" type="Int32" unsaved-value="0">
                
          <generator class="identity"/>
              
          </id>
              
          <property name="ClassesName" column="ClassName" type="String" length="50"/>

              
          <bag name="StudentList" cascade="all"  inverse="true">
                
          <key column="ID" />
                
          <one-to-many class="NHibernateTest.Student,NHibernateTest" />
              
          </bag>
            
          </class>
          </hibernate-mapping>

            如映射文件所示,one-to-many標(biāo)簽必須包含在標(biāo)簽bag中(個(gè)人理解:多嘛,就用一個(gè)包裝起來~)
                  bag標(biāo)簽的name屬性指出Address對(duì)象用哪個(gè)屬性和Student對(duì)象關(guān)聯(lián),inverse屬性使collection不更新連接(總之,這個(gè)屬性提高了性能,具體的情況請(qǐng)參考NHibernate的幫助文檔).
          key標(biāo)簽的column屬性指出了Address對(duì)象對(duì)應(yīng)的數(shù)據(jù)表用哪個(gè)字段和Student對(duì)象對(duì)應(yīng)的數(shù)據(jù)表關(guān)聯(lián)
          one-to-many標(biāo)簽的class屬性指出了Address和哪個(gè)對(duì)象關(guān)聯(lián).

          對(duì)于Classes類得創(chuàng)建一個(gè)StudentList : Student的屬性,用來描述與Student對(duì)象的關(guān)系.

          many-to-many:多對(duì)多在數(shù)據(jù)庫(kù)中也是常見的數(shù)據(jù)模型,像用戶與組,用戶與權(quán)限等。多對(duì)多關(guān)系需要通過一個(gè)中間表實(shí)現(xiàn),element的就是讀取這個(gè)中間表中某列的值。在本文的例子中,Student類和Subject類是多對(duì)多的關(guān)系.

          Student的映射可能是:

              <bag name="SubjectList" table="r_Student_Subject" inverse="true" cascade="save-update" lazy="false">
                
          <key column="StudentID" />
                
          <many-to-many class="NHibernateTest.Subject,NHibernateTest" column="ID" outer-join="auto" />
              
          </bag>

            在bag標(biāo)簽中,加入了一個(gè)table屬性,它指定一個(gè)實(shí)現(xiàn)多對(duì)多的中間表

          完整的Student.hbm.xml源碼如下:

          <?xml version="1.0" encoding="utf-8" ?>
          <hibernate-mapping xmlns="urn:nhibernate-mapping-2.0">
            
          <class name="NHibernateTest.Student,NHibernateTest" table="Users">
              
          <id name="UserID" column="ID" type="Int32" unsaved-value="0">
                
          <generator class="identity"/>
              
          </id>
              
          <property name="UserName" column="UserName" type="String" length="20"/>
              
          <property name="Password" column="Password" type="String" length="20"/>

              
          <!--Student類和NativePlace類是一對(duì)一的關(guān)系-->
              
          <one-to-one name="NativePlace" class="NHibernateTest.NativePlace,NHibernateTest" cascade="all" />

              
          <!--Student類和Classes類是多對(duì)一的關(guān)系-->
              
          <many-to-one name="Classes" column="cID" unique ="true"/>

              
          <!--Student類和Address類是一對(duì)多的關(guān)系-->
              
          <bag name="AddressList" cascade="all"  inverse="true">
                
          <key column="ID" />
                
          <one-to-many class="NHibernateTest.Address,NHibernateTest" />
              
          </bag>

              
          <!--Student類和Subject類是多對(duì)多的關(guān)系-->
              
          <bag name="SubjectList" table="r_Student_Subject" inverse="true" cascade="save-update" lazy="false">
                
          <key column="StudentID" />
                
          <many-to-many class="NHibernateTest.Subject,NHibernateTest" column="ID" outer-join="auto" />
              
          </bag>
            
          </class>
          </hibernate-mapping>
          Student類得添加類型為IList的屬性SubjectList表示與類Subject的關(guān)系.

          由于Student的映射關(guān)系比較復(fù)雜,本文就再熬述它的CRUD操作,具體的操作方法請(qǐng)參考本文附帶的代碼.

          posted on 2009-06-11 15:51 lau 閱讀(4054) 評(píng)論(0)  編輯  收藏 所屬分類: Hibernate


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


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 扎赉特旗| 深泽县| 上林县| 枣阳市| 孟村| 钟祥市| 东方市| 泉州市| 莒南县| 溆浦县| 巴塘县| 印江| 泸西县| 南乐县| 百色市| 扎赉特旗| 江油市| 和龙市| 古交市| 安阳市| 扬中市| 大英县| 酒泉市| 西丰县| 新野县| 兴宁市| 南和县| 云霄县| 白朗县| 都兰县| 临城县| 长垣县| 平邑县| 云霄县| 肥城市| 栖霞市| 肥东县| 忻州市| 托克逊县| 和政县| 南充市|