Hibernate的一对一关联实例<转>

Hibernate的一对一关联实例

Hibernate中的表的关联有一对一,一对多和多对多三种关联方式,在这篇笔记和接下来的笔记中,我将用我自己的实际例子来说明如何具体实施。
      我使用的Hibernate版本是2.1.8,在Hibernate的网站2.1.6版本的中文文档中有关一对一的关联有下面一段表述:

5.1.11. 一对一
持久化对象之间一对一的关联关系是通过one-to-one元素定义的。 

< one-to-one
        
name ="propertyName"                                 (1)
        class
="ClassName"                                   (2)
        cascade
="all|none|save-update|delete"               (3)
        constrained
="true|false"                            (4)
        outer-join
="true|false|auto"                        (5)
        property-ref
="propertyNameFromAssociatedClass"      (6)
        access
="field|property|ClassName"                   (7)
        
/>
(1) name: 属性的名字。 
 
(2) class (可选 - 默认是通过反射得到的属性类型):被关联的类的名字。 
 
(3) cascade(级联) (可选) 表明操作是否从父对象级联到被关联的对象。 
 
(4) constrained(约束) (可选) 表明该类对应的表对应的数据库表,和被关联的对象所对应的数据库表之间,通过一个外键引用对主键进行约束。这个选项影响save()和delete()在级联执行时的先后顺序(也在schema export tool中被使用)。 
 
(5) outer-join(外连接) (可选 - 默认为 自动): 当设置hibernate.use_outer_join的时候,对这个关联允许外连接抓取。 
 
(6) property-ref: (可选) 指定关联类的一个属性,这个属性将会和本外键相对应。如果没有指定,会使用对方关联类的主键。 
 
(7) access (可选 - 默认是 property): Hibernate用来访问属性的策略。 
 

有两种不同的一对一关联: 

主键关联 

惟一外键关联 

主键关联不需要额外的表字段;两行是通过这种一对一关系相关联的,那么这两行就共享同样的主关键字值。所以如果你希望两个对象通过主键一对一关联,你必须确认它们被赋予同样的标识值! 

比如说,对下面的Employee和Person进行主键一对一关联: 

< one-to-one  name ="person"  class ="Person" />
< one-to-one  name ="employee"  class ="Employee"  constrained ="true" />
现在我们必须确保PERSON和EMPLOYEE中相关的字段是相等的。我们使用一个特别的称为foreign的Hibernate标识符生成器策略: 

< class  name ="person"  table ="PERSON" >
    
< id  name ="id"  column ="PERSON_ID" >
        
< generator  class ="foreign" >
            
< param  name ="property" > employee </ param >
        
</ generator >
    
</ id >
    
    
< one-to-one  name ="employee"
        class
="Employee"
        constrained
="true" />
</ class >
一个刚刚保存的Person实例被赋予和该Person的employee属性所指向的Employee实例同样的关键字值。 

另一种方式是一个外键和一个惟一关键字对应,上面的Employee和Person的例子,如果使这种关联方式,应该表达成: 

< many-to-one  name ="person"  class ="Person"  column ="PERSON_ID"  unique ="true" />
如果在Person的映射加入下面几句,这种关联就是双向的: 

< one-to-one  name"employee" class ="Employee"  property-ref ="person" />
      
      下面是我的一个一对一主键关联的例子,使用的数据库是MySQL 4.1.11:
      我有两个表:UserBasic和UserInfo,UserBasic记录的是用户的基本注册信息,UserInfo表记录的是用户的详细信息。表的结构如下:

 1 CREATE   TABLE   IF   NOT   EXISTS  UserBasic
 2 (
 3    Guid                            INT                              NOT   NULL  AUTO_INCREMENT,
 4    Account                         VARCHAR ( 64 )                     NOT   NULL ,
 5    Password                        VARCHAR ( 16 )                     NOT   NULL ,
 6    Email                           VARCHAR ( 128 )                    NOT   NULL ,
 7     PRIMARY   KEY  (Guid)
 8 ) TYPE = InnoDB;
 9
10 CREATE   TABLE   IF   NOT   EXISTS  UserInfo
11 (
12    Guid                            INT                              NOT   NULL ,
13    Username                        VARCHAR ( 128 ),
14    Gender                          CHAR ( 1 ),
15    Birthday                        DATETIME ,
16     PRIMARY   KEY  (Guid)
17 ) TYPE = InnoDB;
18
19 ALTER   TABLE  UserInfo  ADD   CONSTRAINT  UserInfoRFUserBasic  FOREIGN   KEY  (Guid) 
20     REFERENCES  UserBasic (Guid)  ON   DELETE   CASCADE   ON   UPDATE   RESTRICT ;

      UserInfo的主键值和UserBasic的主键值是一样的,两个表是单向的一对一关系。UserBasic为主控方,UserInfo是被动方。
      用Middlegen生成的UserBasic.hbm.xml文件,修改后的内容如下:

  1 <? xml version="1.0" ?>
  2 <! DOCTYPE hibernate-mapping PUBLIC
  3     "-//Hibernate/Hibernate Mapping DTD 2.0//EN"
  4     "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd"  >
  5     
  6 < hibernate-mapping >
  7 <!--  
  8     Created by the Middlegen Hibernate plugin 2.1
  9
 10     http://boss.bekk.no/boss/middlegen/
 11     http://www.hibernate.org/
 12 -->
 13
 14 < class 
 15      name ="com.xxx.hibernate.UserBasic"  
 16     table ="UserBasic"
 17     dynamic-update ="true"
 18     dynamic-insert ="true"
 19 >
 20      < meta  attribute ="class-description"  inherit ="false" >
 21        @hibernate.class
 22         table="UserBasic"
 23         dynamic-update="true"
 24         dynamic-insert="true"
 25      </ meta >
 26
 27      < id
 28          name ="guid"
 29         type ="int"
 30         column ="Guid"
 31      >
 32          < meta  attribute ="field-description" >
 33            @hibernate.id
 34             generator-class="native"
 35             type="int"
 36             column="Guid"
 37
 38
 39          </ meta >
 40          < generator  class ="native"   />
 41      </ id >
 42
 43      < property
 44          name ="account"
 45         type ="java.lang.String"
 46         column ="Account"
 47         not-null ="true"
 48         length ="64"
 49      >
 50          < meta  attribute ="field-description" >
 51            @hibernate.property
 52             column="Account"
 53             length="64"
 54             not-null="true"
 55          </ meta >     
 56      </ property >
 57      < property
 58          name ="password"
 59         type ="java.lang.String"
 60         column ="Password"
 61         not-null ="true"
 62         length ="16"
 63      >
 64          < meta  attribute ="field-description" >
 65            @hibernate.property
 66             column="Password"
 67             length="16"
 68             not-null="true"
 69          </ meta >     
 70      </ property >
 71      < property
 72          name ="email"
 73         type ="java.lang.String"
 74         column ="Email"
 75         not-null ="true"
 76         length ="128"
 77      >
 78          < meta  attribute ="field-description" >
 79            @hibernate.property
 80             column="Email"
 81             length="128"
 82             not-null="true"
 83          </ meta >     
 84      </ property >
 85
 86      <!--  Associations  -->
 87   
 88      <!--  bi-directional one-to-one association to UserInfo  -->
 89      < one-to-one
 90          name ="userInfo"
 91         class ="com.xxx.hibernate.UserInfo"
 92         cascade ="save-update"
 93      >
 94          < meta  attribute ="field-description" >
 95            @hibernate.one-to-one
 96               class="com.xxx.hibernate.UserInfo"
 97             cascade="save-update"
 98          </ meta >
 99      </ one-to-one >
100
101 </ class >
102 </ hibernate-mapping >

      由于在建立外键的时候就声明了ON DELETE CASCADE,所以在xml的配置文件中第97行声明为save-update。如果声明为all,那么在删除UserBasic表的数据时,会无谓的多出一条删除UserInfo的delete语句出来。
      UserInfo.hbm.xml文件的内容如下:

 1 <? xml version = " 1.0 " ?>
 2 <! DOCTYPE hibernate - mapping PUBLIC
 3      " -//Hibernate/Hibernate Mapping DTD 2.0//EN "
 4      " http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd "   >
 5     
 6 < hibernate - mapping >
 7 <!--  
 8     Created by the Middlegen Hibernate plugin  2.1
 9
10     http: // boss.bekk.no/boss/middlegen/
11     http: // www.hibernate.org/
12 -->
13
14 < class  
15     name = " com.xxx.hibernate.UserInfo "  
16     table = " UserInfo "
17     dynamic - update = " true "
18     dynamic - insert = " true "
19 >
20      < meta attribute = " class-description "  inherit = " false " >
21        @hibernate. class
22         table = " UserInfo "
23         dynamic - update = " true "
24         dynamic - insert = " true "
25      </ meta >
26
27      < id
28         name = " guid "
29         type = " int "
30         column = " Guid "
31      >
32          < meta attribute = " field-description " >
33        
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值