在Hibernate 关系映射中一对一是比较常见也常用的一种,一对一的关系映射类型中又可分为:一对一外键单向映射、一对一外键双向映射、一对一主键单向映射和一对一主键双向映射。
下面就简单的说下自己对这几种映射的理解:
一对一外键单向映射,既然是外键那么映射关系可以理解为是由添加外键的一端来维护的,这里我们暂时称之为“主动维护的一端”(下面简称“主”),那么另外一个类暂时称之为“被维护一端”(下面简称“被”)。主动维护的一端需要额外的添加外键来主动维护这种关系,“主”端生成外键的时候要参照“被”端的主键,也就是说“主”外键依赖于“被”端主键。
那么只需要在主.hbm.xml 的配置文件中添加一个<many-to-one name="被在主里面定义的字段" unique="true" />的标签来指向“被”端就可以了,而“被”.hbm.xml不需要添加额外的标签。这里在many-to-one标签中要特别指定unique="true" 属性,这个其实就是多对一关系映射中的一种特殊情况。 多对一的映射关系后面再介绍。
找个实例拿过来看看: “主”端 (数据库表中会生成 id 、name、idCard 三个相应的字段)
<class name="Person" table="t_person">
<id name="id">
<!--native 主键生成策略 -->
<generator class="native"/>
</id>
<property name="name"/>
<!-- (可选): 使用DDL为外键字段生成一个唯一约束。此外,这也可以用作property-ref 的目标属性。这使关联同时具有 一对一的效果。 -->
<many-to-one name="idCard" unique="true"/>
</class>
“被”端:
<class name="IdCard" table="t_idcard">
<id name="id">
<!-- 主键生成策略 -->
<generator class="native"/>
</id>
<property name="cardNo"/>
</class>
一对一外键双向映射,这种关系映射在配置的时候其实就是一对一外键单向配置的基础上再在“被”的一端添加一个<one-to-one name="在被端POJO里面定义的主类型的变量名称"/>
双向的,“主”端和上面的一样;“被“的一端变为: (数据库表t_idcard中生成两个字段,id 、carNo),IdCard 的POJO中也声明了person 但数据库表中不会生成相应的字段。
<class name="IdCard" table="t_idcard">
<id name="id">
<generator class="native"/>
</id>
<property name="cardNo"/>
<one-to-one name="person" property-ref="idCard"/>
</class>
一对一主键单向映射,主键的话就不用在数据库表中添加额外的字段了,这里主动维护的一端的主键的生成要依赖于被维护端的主键。这里在主动维护的一端的*hbm.xml文件中定义主键的生成策略为forergn 例如:
"主"端:
<hibernate-mapping>
<calss name="Person" table="t_person">
<id name="id">
<generator calss="foreign">
<param name="property">idCard</param>// 主键生成参照的哪个外键的名称,这里要和下面的<one-to-one name="idCard"/>标签的属性保持一致。
<generator>
</id>
<property name="name"/>
<one-to-one name="idCard" constrained="true"/>// <one-to-one>标签来维护映射关系。constrained 表示是否支持级联关系 默认为false 这里设置为true ,在生成
// 两个对象间的关系的时候就不用关心先后顺序
</class>
</hibernate-mapping>
“被”端: 基本上和前面的一样,单向的时候基本上不会添加用于映射的标签。
<hibernate-mapping>
<calss name="IdCard" table="t_idcard">
<id name="id">
<generator calss="uuid.hex"/>
</id>
<property name="cardNo"/>
</calss>
<hibernate-mapping>
一对一主键双向映射: 双向的时候只是在单向映射的基础上在“被”端添加一个<one-to-one>的标签来设置从被的一端维护这种关系。
“主”端和上面是一样的,看“被”端
<hibernate-mapping>
<calss name="IdCard" table="t_idcard">
<id name="id">
<generator calss="native">
</id>
<property name="cardNo"/>
<one-to-one name="person"/>
</class>
</hibernate-mapping>
一对一几种关系映射先写到这,下一篇总结多对一 和一对多映射。