每日一得

          不求多得,只求一得 about java,hibernate,spring,design,database,Ror,ruby,快速開發(fā)
          最近關心的內(nèi)容:SSH,seam,flex,敏捷,TDD
          本站的官方站點是:顛覆軟件

            BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
            220 隨筆 :: 9 文章 :: 421 評論 :: 0 Trackbacks
          key words:hibernate,復合主鍵,composite-id



          基于業(yè)務需求,您會需要使用兩個字段來作復合主鍵,例如在User數(shù)據(jù)表中,您也許會使用"name""phone"兩個字段來定義復合主鍵。

          假設您這么建立User表格:

          CREATE?TABLE?user?(

          ????name?
          VARCHAR(100)?NOT?NULL,

          ????phone?
          VARCHAR(50)?NOT?NULL,

          ????age?
          INT,

          ????
          PRIMARY?KEY(name,?phone)

          );

          在表格中,"name""age"被定義為復合主鍵,在映像時,您可以讓User類別直接帶有"name""age"這兩個屬性,而Hibernate要求復合主鍵類別要實作Serializable接口,并定義equals()hashCode()方法:

          User.java

          package?onlyfun.caterpillar;

          ?

          import?java.io.Serializable;

          import?org.apache.commons.lang.builder.EqualsBuilder;

          import?org.apache.commons.lang.builder.HashCodeBuilder;

          ?

          //?復合主鍵類的對應類別必須實作Serializable接口

          public?class?User?implements?Serializable?{

          ????
          private?String?name;

          ????
          private?String?phone;

          ????
          private?Integer?age;

          ???

          ????
          public?User()?{

          ????}

          ?

          ????
          public?Integer?getAge()?{

          ????????
          return?age;

          ????}

          ?

          ????
          public?void?setAge(Integer?age)?{

          ????????
          this.age?=?age;

          ????}

          ?

          ????
          public?String?getName()?{

          ????????
          return?name;

          ????}

          ?

          ????
          public?void?setName(String?name)?{

          ????????
          this.name?=?name;

          ????}

          ?

          ????
          public?String?getPhone()?{

          ????????
          return?phone;

          ????}

          ?

          ????
          public?void?setPhone(String?phone)?{

          ????????
          this.phone?=?phone;

          ????}

          ???

          ????
          //?必須重新定義equals()與hashCode()

          ????
          public?boolean?equals(Object?obj)?{

          ????????
          if(obj?==?this)?{

          ????????????
          return?true;

          ????????}

          ???????

          ????????
          if(!(obj?instanceof?User))?{

          ????????????
          return?false;

          ????????}

          ???????

          ????????User?user?
          =?(User)?obj;

          ????????
          return?new?EqualsBuilder()

          ?????????????????.append(
          this.name,?user.getName())

          ?????????????????.append(
          this.phone,?user.getPhone())

          ?????????????????.isEquals();

          ???????

          ????}

          ???

          ????
          public?int?hashCode()?{

          ????????
          return?new?HashCodeBuilder()

          ?????????????????.append(
          this.name)

          ?????????????????.append(
          this.phone)

          ?????????????????.toHashCode();

          ????}

          }

          equals()hashCode()方法被用作兩筆不同數(shù)據(jù)的識別依據(jù);接著您可以使用<composite-id>在映射文件中定義復合主鍵與對象的屬性對應:

          User.hbm.xml

          <?xml?version="1.0"?encoding="utf-8"?>

          <!DOCTYPE?hibernate-mapping

          ????PUBLIC?"-//Hibernate/Hibernate?Mapping?DTD?3.0//EN"

          ????"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"
          >

          ?

          <hibernate-mapping>

          ?

          ????
          <class?name="onlyfun.caterpillar.User"?table="user">

          ????????
          <composite-id>

          ????????????
          <key-property?name="name"

          ??????????????????????????column
          ="name"

          ??????????????????????????type
          ="java.lang.String"/>

          ????????????
          <key-property?name="phone"

          ??????????????????????????column
          ="phone"

          ??????????????????????????type
          ="java.lang.String"/>

          ????????
          </composite-id>

          ?

          ????????
          <property?name="age"?column="age"?type="java.lang.Integer"/>

          ???

          ????
          </class>

          </hibernate-mapping>

          在儲存數(shù)據(jù)方面,復合主鍵的儲存沒什么區(qū)別,現(xiàn)在的問題在于如何依據(jù)復合主鍵來查詢數(shù)據(jù),例如使用load()方法,您可以創(chuàng)建一個User實例,并設定復合主鍵對應的屬性,接著再透過load()查詢對應的數(shù)據(jù),例如:

          User?user?=?new?User();

          user.setName(
          "bush");

          user.setPhone(
          "0970123456");

          ???????

          Session?session?
          =?sessionFactory.openSession();

          //?以實例設定復合主鍵并加載對應的數(shù)據(jù)

          user?
          =?(User)?session.load(User.class,?user);

          ???????

          System.out.println(user.getAge()?
          +?"\t"?+

          ??????????????????????????????????user.getName()?
          +?"\t"?+

          ??????????????????????????????????user.getPhone());

          session.close();

          ?

          ?

          可以將主鍵的信息獨立為一個類別,例如:

          UserPK.java

          package?onlyfun.caterpillar;

          ?

          import?java.io.Serializable;

          ?

          import?org.apache.commons.lang.builder.EqualsBuilder;

          import?org.apache.commons.lang.builder.HashCodeBuilder;

          ?

          public?class?UserPK?implements?Serializable?{

          ????
          private?String?name;

          ????
          private?String?phone;

          ?

          ????
          public?String?getName()?{

          ????????
          return?name;

          ????}

          ?

          ????
          public?void?setName(String?name)?{

          ????????
          this.name?=?name;

          ????}

          ?

          ????
          public?String?getPhone()?{

          ????????
          return?phone;

          ????}

          ?

          ????
          public?void?setPhone(String?phone)?{

          ????????
          this.phone?=?phone;

          ????}

          ???

          ????
          public?boolean?equals(Object?obj)?{

          ????????
          if(obj?==?this)?{

          ????????????
          return?true;

          ????????}

          ???????

          ????????
          if(!(obj?instanceof?User))?{

          ????????????
          return?false;

          ????????}

          ???????

          ????????UserPK?pk?
          =?(UserPK)?obj;

          ????????
          return?new?EqualsBuilder()

          ?????????????????.append(
          this.name,?pk.getName())

          ?????????????????.append(
          this.phone,?pk.getPhone())

          ?????????????????.isEquals();

          ???????

          ????}

          ???

          ????
          public?int?hashCode()?{

          ????????
          return?new?HashCodeBuilder()

          ?????????????????.append(
          this.name)

          ?????????????????.append(
          this.phone)

          ?????????????????.toHashCode();

          ????}

          }

          現(xiàn)在User類別的主鍵信息被分離出來了,例如:

          User.java

          package?onlyfun.caterpillar;

          ?

          import?java.io.Serializable;

          ?

          public?class?User?implements?Serializable?{

          ????
          private?UserPK?userPK;?//?主鍵

          ????
          private?Integer?age;

          ???

          ????
          public?User()?{

          ????}

          ?

          ????
          public?UserPK?getUserPK()?{

          ????????
          return?userPK;

          ????}

          ?

          ????
          public?void?setUserPK(UserPK?userPK)?{

          ????????
          this.userPK?=?userPK;

          ????}

          ?

          ????
          public?Integer?getAge()?{

          ????????
          return?age;

          ????}

          ?

          ????
          public?void?setAge(Integer?age)?{

          ????????
          this.age?=?age;

          ????}

          }

          在映像文件方面,需要指定主鍵類的信息,例如:

          User.hbm.xml

          <?xml?version="1.0"?encoding="utf-8"?>

          <!DOCTYPE?hibernate-mapping

          ????PUBLIC?"-//Hibernate/Hibernate?Mapping?DTD?3.0//EN"

          ????"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"
          >

          ?

          <hibernate-mapping>

          ?

          ????
          <class?name="onlyfun.caterpillar.User"?table="user">

          ????????
          <composite-id?name="userPK"

          ??????????????????????class
          ="onlyfun.caterpillar.UserPK"

          ??????????????????????unsaved-value
          ="any">

          ????????????
          <key-property?name="name"

          ??????????????????????????column
          ="name"

          ??????????????????????????type
          ="java.lang.String"/>

          ????????????
          <key-property?name="phone"

          ??????????????????????????column
          ="phone"

          ??????????????????????????type
          ="java.lang.String"/>

          ????????
          </composite-id>

          ???????

          ????????
          <property?name="age"?column="age"?type="java.lang.Integer"/>

          ???

          ????
          </class>

          ?

          </hibernate-mapping>

          在查詢數(shù)據(jù)時,必須指定主鍵信息,例如:

          UserPK?pk?=?new?UserPK();

          pk.setName(
          "bush");

          pk.setPhone(
          "0970123456");

          ??????

          Session?session?
          =?sessionFactory.openSession();

          //?以主鍵類實例設定復合主鍵并加載對應的數(shù)據(jù)

          User?user?
          =?(User)?session.load(User.class,?pk);

          ??????

          System.out.println(user.getAge()?
          +?"\t"?+

          ??????????????????????????????????user.getUserPK().getName()?
          +?"\t"?+

          ??????????????????????????????????user.getUserPK().getPhone());

          session.close();

          ?


          =================================================
          再參考robbin的一篇文章
          一個簡單的復合主鍵的做關聯(lián)類的例子??
          posted on 2006-11-09 19:22 Alex 閱讀(12935) 評論(5)  編輯  收藏 所屬分類: Hibernate

          評論

          # re: [zt]hibernate復合主鍵 2009-05-27 21:38 lmzh-scut
          could not initialize proxy - no Session
          何解?  回復  更多評論
            

          # re: [zt]hibernate復合主鍵 2009-08-13 17:15 溫薔薇
          我暈····················很簡單的問題把它復雜化了·  回復  更多評論
            

          # re: [zt]hibernate復合主鍵 2009-09-18 13:41 sunning
          明白了。謝謝  回復  更多評論
            

          # re: [zt]hibernate復合主鍵 2014-05-19 20:09 cvx
          cxcxc  回復  更多評論
            

          # re: [zt]hibernate復合主鍵 2014-05-19 20:09 hfiusdfhsudifhsidua
          dsd  回復  更多評論
            

          主站蜘蛛池模板: 平山县| 荔波县| 温泉县| 遵义县| 宁陵县| 乌海市| 壶关县| 新沂市| 邵武市| 海南省| 沙坪坝区| 九龙城区| 丽水市| 桦南县| 九台市| 平顺县| 永靖县| 明溪县| 门头沟区| 周至县| 江川县| 石城县| 中超| 巴东县| 密山市| 江永县| 红桥区| 郑州市| 罗城| 增城市| 班玛县| 崇明县| 西充县| 东城区| 武义县| 驻马店市| 阳江市| 天峨县| 泊头市| 来安县| 临海市|