每日一得

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

            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
            220 隨筆 :: 9 文章 :: 421 評論 :: 0 Trackbacks
          <2014年5月>
          27282930123
          45678910
          11121314151617
          18192021222324
          25262728293031
          1234567

          常用鏈接

          留言簿(23)

          隨筆分類(240)

          隨筆檔案(219)

          文章分類(9)

          文章檔案(9)

          收藏夾(15)

          java link

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          key words:hibernate,復合主鍵,composite-id



          基于業務需求,您會需要使用兩個字段來作復合主鍵,例如在User數據表中,您也許會使用"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()方法被用作兩筆不同數據的識別依據;接著您可以使用<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>

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

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

          user.setName(
          "bush");

          user.setPhone(
          "0970123456");

          ???????

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

          //?以實例設定復合主鍵并加載對應的數據

          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();

          ????}

          }

          現在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>

          在查詢數據時,必須指定主鍵信息,例如:

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

          pk.setName(
          "bush");

          pk.setPhone(
          "0970123456");

          ??????

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

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

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

          ??????

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

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

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

          session.close();

          ?


          =================================================
          再參考robbin的一篇文章
          一個簡單的復合主鍵的做關聯類的例子??
          posted on 2006-11-09 19:22 Alex 閱讀(12936) 評論(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  回復  更多評論
            

          主站蜘蛛池模板: 东平县| 麦盖提县| 云林县| 宁远县| 郎溪县| 石家庄市| 雷波县| 视频| 平和县| 革吉县| 宁蒗| 长治县| 进贤县| 顺昌县| 济南市| 上林县| 连山| 家居| 祁连县| 东莞市| 东安县| 黄梅县| 盘锦市| 泽库县| 定结县| 建始县| 阿拉善右旗| 汉寿县| 安远县| 浮山县| 丹棱县| 清徐县| 汉沽区| 莱阳市| 绥阳县| 萝北县| 东明县| 沾益县| 岗巴县| 乌兰察布市| 钦州市|