您的位置:首页 > 其它

hibernate关系映射 一对一

2014-11-03 21:16 225 查看
接下来的这几篇博客说的是“实体关系映射”。

一、关系 & 映射

我们先将关系映射,我们拆成“关系”和“映射”两部分。



关系:不陌生,在“程序员”的概念里最基本的就是表表之间的关系,类类之间的关系,这里要说的关系就这两种。一个系统中的任何一个实体都不是独立的,这就是我们类图中各个类之间的相互引用。类图间的关系表现在数据库中,就是表之间的的外键约束。这些关系有:一对一,一对多,多对一,多对多,继承。 关系的使用,就涉及到方向的问题,所以,以上几种关系都有方向存在。

回想之前的设计,step1:类的设计是一部分,形成OOM,拿着oom来生成我们的“代码”;

step2:数据库的设计是另一部分,形成PDM,用PDM形成database。

当然都知道利用powerdesigner 等工具,在oom和pdm之间,是可以相互转换的,编程的工作量是大大减轻了,即便这样,还是有更先进的思想,来解放我们的劳动力,在哪?就是hibernate。



映射:将实体映射到数据库,基于实体间的关系,这里的一个“映射”包含了N多种情况,hibernate是怎么节省工作量的呢?hibernate将之前的两步,做成了“一步到位”。从代码开始设计对象,通过“xml”映射到数据库。hibernate使编程更专注于“对象”的设计。那么系统中“对象”键的关系是怎么“映射”到数据库中呢?这其中的原理最重要的就是:Hibernate 靠什么来区分对象间的不同关系?hibernate定义了一套“关系”映射的约定,来区分对象之间的不同关系。这样我们以前需要手动去维护的数据表外键约束,就被hibernate给代劳了。

接下来就看看hibernate中的这套约定。



二、关系规范实现

(这篇博客说一对一的关系映射的实现)

一对一

两种实现方式,主键关联映射,唯一外键关联映射。

约定:one-to-one



1、主键关联映射



实现方式:让两个实体的主键一样,这样就不需要加入多余的字段了



单向关联Person----->IdCard

person中存在IdCard的引用,反之没有,对应的,IdCard.hbm.xml 文件不会发生变化。需要在person.hbm.xml中加入维护关系的约定内容。

关系图如下;




实体类实现如下:

<span style="font-family:KaiTi_GB2312;font-size:18px;">			public class Person {
			
				private int id;
				
				private String name;
				
				private IdCard idCard;
			
				public int getId() {
					return id;
				}
			
				public void setId(int id) {
					this.id = id;
				}
			
				public String getName() {
					return name;
				}
			
				public void setName(String name) {
					this.name = name;
				}
			
				public IdCard getIdCard() {
					return idCard;
				}
			
				public void setIdCard(IdCard idCard) {
					this.idCard = idCard;
				}
			}
</span>
person端的hbm.xml编写:


<span style="font-family:KaiTi_GB2312;font-size:18px;">	<class name="com.bjpowernode.hibernate.Person" table="t_person">
		<id name="id">
		<!-- 采用foreign生成策略,forgeign会取得关联对象的标识 -->
			<generator <strong>class="foreign"</strong>>
			<!-- property只关联对象 -->
				<param name="property">idCard</param>
			</generator>
		</id>
		<property name="name"/>
		<strong><one-to-one name="idCard" constrained="true"/></strong>
		<!-- one-to-one指示hibernate如何加载其关联对象,默认根据主键加载也就是拿到关系字段值,根据对端的主键来加载关联对象
			constrained="true表示,当前主键(person的主键)还是一个外键参照了对端的主键(IdCard的主键),也就是会生成外键约束语句 -->
         </class>
</span>


双向关联

在IdCard中加入Person的引用;

在IdCard一段也加入维护关系的约定内容,<one-to-one name="person" />

IdCard配置文件如下:



<span style="font-family:KaiTi_GB2312;font-size:18px;">	<hibernate-mapping>
		<class name="com.bjpowernode.hibernate.IdCard" table="t_idCard">
			<id name="id">
				<generator class="native"/>
			</id>
			<property name="cardNo"/>
			<strong><one-to-one name="person"/></strong>
		</class>
	</hibernate-mapping>
</span>


2、唯一外键关联

引入对端实体的主键做外键约束,来实现,实体都有自己各自的主键,不共享主键。

约定:<many-to-one> & <one-to-one>

一对一唯一外键关联映射其实是多对一的特例,采用<many-to-one>标签来映射,指定多的一端unique为true,这样就限制了多的一端的多重性为一,就是这样来映射的。

数据表图:



person的映射文件如下:

<span style="font-family:KaiTi_GB2312;font-size:18px;"><hibernate-mapping>
	<class name="com.bjpowernode.hibernate.Person" table="t_person">
		<id name="id">
			<generator class="native"/>
		</id>
		property name="name"/>
		<strong><many-to-one name="idCard" unique="true"/></strong>
	</class>
</hibernate-mapping></span>



双向关联实现——one-to-one

这里和一对一主键关联的一点小区别是:唯一外键关联在双向关联的时候,没有外键的一方是一对一的关系,有外键的一方是一对多的关系,所以IdCard使用的是one-to-one

IdCard 映射文件如下:

<span style="font-family:KaiTi_GB2312;font-size:18px;"><hibernate-mapping>
	<class name="com.bjpowernode.hibernate.IdCard" table="t_idCard">
	        <id name="id">
		      <generator class="native"/>
	        </id>
	        <property name="cardNo"/>
	        <strong><one-to-one name="person" property-ref="idCard"/></strong>
        </class>
 </hibernate-mapping>
</span>


两种方式的对比

一对一主键关联
:共用一个主键,耦合性太大,双方关系发生变化,数据库表就得重新建,不建议使用。

唯一外键关联:增加一个字段,来维护关联关系,灵活性增加。如双发关系由一对一向一对多改变的情况下,只需将限制外键的unique设置为false即可实现,建议使用。

下篇博客是一对多的实现
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: