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

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


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


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


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


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属性为关系字段的名称。


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


评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值