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?UserInfo11
(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-alt="Hibernate的一对一联系关系实例<转>" style="max-width: 100%;height: auto;width: auto\9;" src="//img.reader8.net/uploadfile/jiaocheng/20140188/3040/201401301440589455.gif">????????????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???????????????alt="Hibernate的一对一联系关系实例<转>" style="max-width: 100%;height: auto;width: auto\9;" src="//img.reader8.net/uploadfile/jiaocheng/20140188/3040/201401301440589455.gif">????????????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.class22
????????table="UserInfo"23
????????dynamic-update="true"24
????????dynamic-insert="true"25
????</meta>26

27
????<id28
????????name="guid"29
????????type="int"30
????????column="Guid"31
????>32
????????<meta?attribute="field-description">33
???????