Hibernate一对一关联映射和一对多关联映射

一对一关联映射

    一对一是指两个对象之间是一对一的关系,在Hibernate中使用的标签是<one-to-one>标签,这种关联映射可以采用两种策略实现,一种是主键关联,让两个对象具有相同的主键值,数据库表不会有其他的字段来维护他们之间的关系,仅仅通过主键来关联。另一种就是唯一外键关联,从上一篇博客来看,外键关联是多对一的关联映射方式,但是将外键设置为唯一之后,就可以表示一对一的关联关系。

下面我们分别分析这两种方式:

一、一对一主键关联

    1、一对一单向主键关联映射:

如图所示表示两个实体之间的单向关系:


    在Person类中存在一个属性idCard,来关联IdCard类。两个类的主键值字段都是id。

在Person中的映射文件如下:

<hibernate-mapping>
	<class name="com.bjpowernode.hibernate.Person" table="t_person">
		<id name="id">		
			<generator class="foreign">
				<param name="property">idCard</param>
			</generator>
		</id>
		<property name="name"/>
		<one-to-one name="idCard" constrained="true"></one-to-one>
	</class>
</hibernate-mapping>

    主键是id,生成策略采用了foreign(这种生成策略前面的博客已经详细介绍了),foreign会取得关联对象的标识,<param>标签指向关联对象的关联字段,也就idCard。<one-to-one>标签表示一对一关联映射,设置name为idCard,表示根据主键拿到关系字段,根据对端的主键加载关联对象,设置constrained="true",表示当前Person的主键还是一个外键,也就是会生成一个外键约束语句。

    2、一对一双向主键关联映射:

如下图所示是双向关联的两个实体之间的关系图:

     双向关联和单向关联的实质是一样的,只不过在两个实体两端都加上<one-to-one>标签,也即在单向关联的基础上在IdCard的映射文件中也加入<one-to-one>标签,并设置关联字段,双方都持有对方的引用。

     <one-to-onename="person"></one-to-one>,指示hibernate将关联对象Person根据主键加载上来,并且<one-to-one>标签不影响存储,只影响加载。

二、一对一唯一外键关联

    1、一对一唯一外键单向关联:

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

<many-to-onename="idCard" unique="true"></many-to-one>

Person的映射文件如下:

<hibernate-mapping>
	<class name="com.bjpowernode.hibernate.Person" table="t_person">
		<id name="id">
			<generator class="native" />
		</id>
		<property name="name"/>
		<many-to-one name="idCard" unique="true"></many-to-one>
	</class>
</hibernate-mapping>

    2、一对一唯一外键双向关联:

一对一唯一外键关联双向采用<one-to-one>标签来映射,必须指定<one-to-one>标签

中的property-ref属性为关系字段的名称。

在IdCard的映射文件中加入<one-to-one>标签,并且设置property-ref属性为关联字段idCard。

<hibernate-mapping>
	<class name="com.bjpowernode.hibernate.IdCard" table="t_idCard">
		<id name="id">
			<generator class="native"/>
		</id>
		<property name="cardNo"/>
		<one-to-one name="person" property-ref="idCard"></one-to-one>
	</class>
</hibernate-mapping>

    在Person的映射文件中同样采用<many-to-one>标签,和单向的一样。

    一对一的关联映射中的两种映射方式,其中的单向和双向的本质是一样的,主键映射中,关联对象的加载时通过主键完成的,单向关联,只需要一端维护关系,也即在映射文件中<one-to-one>标签设置在一端即可,而双向关联,需要两端都设置<one-to-one>标签,主键关联的维护在两端进行。而在唯一外键关联映射中,同多对一的关联是一样的,只不过需要把多的一端设置为一,变成一对一的映射,unique=”true”就是来完成这种限制,单向关联就是在一端加上<many-to-one>标签,设置unique属性,双向关联就是在另一端加上<one-to-one>标签,设置property-ref属性为关联字段即可。 

一对多关联映射

    前面介绍了多对一的关联映射是如何的,其实一对多的关联和多对一的关联原理上是一样的,都是在多的一端加入一个外键,指向一的一端,不同之处就是不同的维护关系,加载对象的方式不一样。多对一的维护,那么在加载多的时候就会把一加载上来,而一对多的维护,在加载一的时候会把多的一端加载上来,我们以Classes和Student为例,班级和学生就是一对多的关系,如下图所示:

1、一对多单向关联:

    因为是一对多的关系,自然在Classes的一端会有表示Student的集合属性。

Classes类的映射文件:

<hibernate-mapping>
	<class name="com.bjpowernode.hibernate.Classes" table="t_classes">
		<id name="id">
			<generator class="native"/>
		</id>
		<property name="name"/>
		<set name="students">
			 <key column="classesid"></key>
			<one-to-many class="com.bjpowernode.hibernate.Student"/>
		</set>
	</class>
</hibernate-mapping>

    用一个Set集合映射学生,设置<one-to-many>标签,告诉Hibernate多的一端是Student实体,key值中设置字段为classesid,这样在Student的表中会自动增加一个classesid字段。

    因为采用的是单向关联的映射方式,所以在Student的一端并没有和Classes的关联,也就是只有一的对端维护关系,在多的一端没有维护关系,如果在Student表中的classesid设置为空,那么将无法保存数据,一般情况下我们不采用在一的一端维护数据,所以我们采用双向关联的映射,设置成只在Student端维护数据。

2、一对多双向关联映射:

  如下图所示是双向关联的图:


   在单向关联的基础上,在Student中同样添加一个classes属性,维护和Classes的关系,

设置Student的映射文件:

<hibernate-mapping>
	<class name="com.bjpowernode.hibernate.Student" table="t_student">
		<id name="id">
			<generator class="native"/>
		</id>
		<property name="name"/>
		<many-to-one name="classes" column="classesid"></many-to-one>
	</class>
</hibernate-mapping>

    添加<many-to-one>标签表示在多的一端开始维护关系,字段设置为和Classes中添加的key标签中的一样,这里就是维护字段classesid。同样需要撤销在一的一端维护关系,所以设置Classes映射文件中<set>标签中的inverse属性为true,表示本端不维护关系。inverse是控制上的反转,只影响存储,属性默认为false表示本端维护关系,设置为true表示本端不维护关系,由此,就只有多的一端维护关系了。








  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值