Hibernate(五)——经典解析一对一关联映射

来源:互联网 发布:威客网络赚钱平台 编辑:程序博客网 时间:2024/05/24 20:06

前面两篇介绍了多对一、一对多的映射。今天分享下一对一的关联映射关系。有两种策略可以实现一对一的关联映射:主键关联、唯一外键关联。


主键关联——两个表有完全相同的主键值,来表示它们的一对一的关系。数据库中没有额外的字段去维护它们之间的关系,就只是靠着主键来维持关系。


唯一外键关联——增加一个额外的字段,维护他们之间的一对一关系。


现在要用一对一来描述人和身份证的关系。每个人只有一个身份证。


1、单向主键关联进行描述



根据上图,我们需要在person端进行如下配置:

<?xml version="1.0"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN""http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><hibernate-mapping><class name="com.lzq.hibernate.Person" table="t_person"><id name="id"><!--采用foreign生成策略,foreign会取得关联对象的标识--><generator class="foreign"><!--property只关联对象--><param name="property">idCard</param></generator></id><property name="name" /><!-- one-to-one指示hibernate如何加载其关联对象,默认根据主键加载也就是拿到关系字段值,根据对端的主键来加载关联对象 --><one-to-one name="idCard" constrained="true"></one-to-one></class></hibernate-mapping>

主键生成策略使用foreign,它能够取得关联对象的标识。上面代码中“constrained='true'”表示当前主键(person的主键)还是一个外键,参照了对端的主键(IdCard的主键),也就是会生成外键约束语句。


2、单向唯一外键关联

根据上图,我们需要对Person进行如下配置:

<?xml version="1.0"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN""http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><hibernate-mapping><class name="com.lzq.hibernate.Person" table="t_person"><id name="id"><generator class="native" /></id><property name="name" />                <!-- 用多对一的配置+唯一的限制,来表示一对一的关联关系-->                <many-to-one name="idCard" unique="true" /></class></hibernate-mapping>


唯一外键关联的主键生成策略不像主键关联那样必须使用foreign外键生成策略,这里采用的是native。另外一对一的关系采用多对一的配置+唯一的限制,来表示一对一的关联关系。


3、双向主键关联进行描述

该种情况,我们仍然在Person端维护关系字段,而且不能够在IdCard再维护关系。如果在IdCard端也维护关系,两段都维护主键,那么就会产生混乱。所以,此处的双向,我们单只加载的时候,也可以从IdCard方加载上来。




在双向关系中,还需要将关系配置在IdCard中,对IdCard进行如下配置:


<?xml version="1.0"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN""http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><hibernate-mapping><class name="com.lzq.hibernate.IdCard" table="t_id_card"><id name="id"><generator class="native" /></id><property name="cardNo" /><!-- 这是默认情况:由于抓去策略不同,只显示一条sql语句 <one-to-one name="person" fetch="join"></one-to-one> --> <!-- 由于抓去策略不同,显示两条sql语句: 第一条查询身份证,第二条查询人  --> <one-to-one name="person" fetch="select"></one-to-one></class></hibernate-mapping>


双向一对一主键关联映射需要在IdCard加入<one-to-one>标签,指是hibernate将关联对象Person根据主键加载上来。


4、双向唯一外键关联描述

此处的双向同上面提到的双向的概念一致,关系还是只是Person端维护,这里双向只是指从IdCard端能够加载上来。


IdCard端关系:

<?xml version="1.0"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN""http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><hibernate-mapping><class name="com.lzq.hibernate.IdCard" table="t_id_card"><id name="id"><generator class="native" /></id><property name="cardNo" /> <one-to-one name="person" property-ref="idCard"></one-to-one></class></hibernate-mapping>


一对一双向外键关联采用<one-to-one>标签映射,必须执行该标签中的property-ref属性为关系字段的名称。


一对一的关联映射,经常使用的还是单向唯一外键关联。主键关联的方式扩展性不好,而且不太灵活。两种方式的区别在文章开头也有提到,映射方式肯定是不同的,另外在数据库表也有不同,主键关联的方式不会使用额外的字段来维护关系,而唯一外键关联方式需要在一端使用额外的字段维护关系。


原创粉丝点击