上篇博客写了1和n的关联映射,这里继续介绍1:1 的关联映射,看映射文件如何配置。
一、单向主键(persoon---->IdCard)
主键一样,其中一边主键也是外键
1、对象模型
每个person有唯一的IdCard,person维护关系,持有idCard的引用
2、实体模型
t_person的id既是主键也是外键,一个人有唯一的身份证号,从person中可以看到idCard,反过来不行
3、映射文件
IdCard:
<hibernate-mapping>
<class name="com.zx.hibernate.IdCard" table="t_idCard">
<id name="id">
<generator class="native" />
</id>
<property name="cardNo" />
</class>
</hibernate-mapping>
person:
<hibernate-mapping>
<class name="com.zx.hibernate.Person" table="t_person">
<id name="id">
<!-- 采用foreign生成策略,会取得关联对象的标识 -->
<generator class="foreign" >
<!-- property只关联对象<span style="font-family:FangSong_GB2312;">,值是person持有引用</span>-->
<param name="property">idcard</param>
</generator>
</id>
<property name="name" />
<!--
one-to-one标签指示hibernate如何加载其关联对象,默认根据主键加载
也就是拿到关系字段值,根据对端的主键加载关联对象
constrained="true" 表示当前主键(person中的主键)还是一个外键
参照对端的主键(IdCard的主键),生成外键约束语句
-->
<one-to-one name="idcard" constrained="true"/>
</class>
</hibernate-mapping>
生成的表在person中加了约束,person的id是外键参照对端的主键,但是person中不添加多余字段
二、双向主键(person----IdCard)
也就是从person可以看到idcard,从idcard可以看到person。对象模型和上面的相似,只是没有箭头。双方都持有对方的引用。映射文件中需要在idcard中加标签,即关联对象。如下:
<hibernate-mapping>
<class name="com.zx.hibernate.IdCard" table="t_idCard">
<id name="id">
<generator class="native" />
</id>
<property name="cardNo" />
<one-to-one name="person" />
</class>
</hibernate-mapping>
这样就建立了双向关联,name是持有的引用的名字。<one-to-one>不影响存储,只影响加载,不会修改数据库,<many-to-one>会修改数据库。查询idcard也会自动加载person对象。
三、单向唯一外键
就是平时设计数据库的外键,只是外键是唯一的。是多对一个特殊情况。对象模型和上面的相同,映射文件idcard没有变化,都是普通属性。person按照多对一的配置,只是要设置唯一性
<hibernate-mapping>
<class name="com.zx.hibernate.Person" table="t_person">
<id name="id">
<generator class="native" >
<param name="property">idcard</param>
</generator>
</id>
<property name="name" />
<many-to-one name="idcard" unique="true"/>
</class>
</hibernate-mapping>
四、双向唯一外键
对象模型变为双向,互相持有对方的引用,只是idcard查询的时候自动加载person。所以要加关系字段在idcard类和映射文件中。如下:
<hibernate-mapping>
<class name="com.zx.hibernate.IdCard" table="t_idCard">
<id name="id">
<generator class="native" />
</id>
<property name="cardNo" />
<one-to-one name="person" property-ref="idcard"/>
</class>
</hibernate-mapping>
一对一唯一外键关联双向采用<one-to-one>标签映射,必须指定标签中的属性:property-ref="idcard",这个属性为关系字段的名称。这个值必须和person中外键值一致,那样加载的时候会自动查找。
根据一段代码看看如何根据idcard查找person:
public void testoad2(){
Session session = null;
try{
session = hibernateUtils.getSession();
session.beginTransaction();
IdCard idcard = (IdCard)session.load(IdCard.class,1 );
System.out.println("cardNo=" + idcard.getCardNo());
System.out.println("idcard.person.name=" + idcard.getPerson().getName());
session.getTransaction().commit();
}catch(Exception e){
e.printStackTrace();
session.getTransaction().rollback();
}finally{
hibernateUtils.closeSession(session);
}
}
五、总结
1、主键约束要求对象有相同的主键值,表名它们一一对应的关系,扩充性不好
2、一对一唯一外键关联就是多对一的特例,限制了唯一性,扩展性好,如果遇到1:1的建议使用这种方式
3、使用的比较多的是多对一,一对一相当少些