【Hibernate步步为营】--单向关联一对一映射(一)

上篇文章对多对一的关联映射做了详细的分析,它在实现上可以有两种方式,并且这两种方式实现也很简单,关键是标签<many-to-one>的使用,它分别指明了多端和一端的映射关系,这种映射关系既是对象模型中的聚合关系。接下来继续讨论关联映射。

一、唯一外键

唯一外键说的是数据库表中的每一行的外键唯一对应着另一张表中的主键,也就是说一个表的主键作为另一张表的外键,并且它们之间的关系是唯一的,这种反应到关系模型中如下图所示:

上图的两个实体表,分别为人和身份证,很明显的一个人对应着一个身份证。身份证作为一个单独的实体表它添加了标识列,而且此标识列是人实体表中的外键先关联。这种在实现上类似于上篇文章中讲到的多对一映射,一个表的主键标识列是另一张表的外键,所在在实现时使用的也应该是<many-to-one>标签,但不同的是这里采用的是唯一对应,此时应该设置其它的属性来做唯一标识。

为了实现一对一的唯一外键映射,这时就必须在<many-to-one>标签中添加上属性unique,也就是指定多的一端的unique值为true,反应到该示例中也就是在person的映射文件中设置一个<many-to-one name="idCard">标签,并且标签中需要添加unique="true",所以对应的Person.java的映射文件Person.hbm.xml的代码如下:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 2014-5-15 23:47:00 by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
    <class name="com.hibernate.Person" table="PERSON">
        <id name="id" type="int">
            <generator class="native"/>
        </id>
	<property name="name"></property>
	<many-to-one name="idCard" unique="true"></many-to-one>
    </class>
</hibernate-mapping>

对比多对一关联映射和一对一唯一外键关联映射,其实它们两个都是使用了<many-to-one>本质上都是外键约束,只不过一对一的是唯一映射,需要添加unique="true"的属性,其它的它们两个是相同的。

二、主键关联映射

上文讨论了一对一的唯一外键映射,它其实是多对一关联映射的一种特殊情况,并且在关联映射中会有多种情况,这里再继续讨论关联映射可能的情况。

在一对一的关联映射中会有一种特殊的情况就是一个表的主键同时也是一个表的外键,也就是说一个字段是同是主键和外键,并且该外键唯一对应着另一张表的一行,它们两个是唯一对应的关系,反应到对象模型中它们之间属于一种一对一的引用关系,一个对象的属性是另外一个对象的属性值,对象模型如下图所示:

上图的Person类和IdCard类之间是一一对应的关系,一个人就只能有一个身份证,一个身份证只能对应一个人,并且身份证的标识同时也是人的标识,它所对应的关系模型也是一种一对一的关系,一张的主键也是这张表的外键,如下图所示:

T_person表的主键id列同时也是T_idCard表的主键标识列,这就构成了外键关系,所以此时它们之间就是一种一对一的主键关联关系,那么反应到Hibernate中是如何实现的呢?

Hibernate提供的这种映射关联中不但有<many-to-one>的关系,另外还提供了<one-to-one>的关系,它既是指一对一的关系。

在实现时需要将标识字段设置为foreign,并将需要关联的对象的名称作为property参数写入到构造器中,并在最后添加<one-to-one>标签。具体代码如下:

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

			constrained=true表示当前主键(person的主键)还是一个外键,参照了对端的主键(IdCard的主键),也就是会生成外键约束语句
		 -->
		<one-to-one name="idCard" constrained="true"></one-to-one>

    </class>
</hibernate-mapping>

上面的示例中的<param name="property">idCard</param>指的是在Person.java中有一个idCard的属性,该属性是Person对象的一个关联对象,所以需要注册到foreign中,取得关联对象的标识。另外在<one-to-one>标签中添加了一个属性constrained="true",指示了Person对象的主键同时又是一个外键。具体的Person.java中的代码如下:

package com.hibernate;

public class Person {

	private IdCard idCard;
	public IdCard getIdCard() {
		return idCard;
	}
	public void setIdCard(IdCard idCard) {
		this.idCard = idCard;
	}

	private int id;
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}

	private String name;
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
}

其中的idCard是Person对象的一个属性,所以在一对一主键关联映射时需要添加一个标识列。

结语

上文介绍了两种一对一的映射,并且分别从对象模型和关系模型上进行了讨论,对于唯一外键的映射来说它是多对一映射的一种特殊情况,只需要在<many-to-one>中添加unique唯一键即可,另外还有唯一主键映射,这种其实需要<one-to-one>标签,然后在主键的属性中使用foreign生成策略,并在该映射中添加对应的关联对象。一对一的映射是还有很多种情况,将会在接下来的文章中讨论。

【Hibernate步步为营】--单向关联一对一映射(一),布布扣,bubuko.com

时间: 2024-10-11 09:28:12

【Hibernate步步为营】--单向关联一对一映射(一)的相关文章

【Hibernate步步为营】--双向关联一对一映射详解(二)

很不好意思,有两天时间没有更新博客文章了,不写文章的日子还真是感觉很空洞啊,养成了写文章的恶习想改也改不掉啊.说点题外话,前两天收到一位朋友的私信,邀请笔者写一篇有关OWS的文章,用来研究图标工具的一种技术,很荣幸收到这位朋友的邀请,但是因为这几天开发的项目着急上线所以暂时没有时间去研究,只能等这周末了,利用周末的时间来研究然后更新类似的技术文章. 回到文章的正题,上篇文章讨论了双向主键关联,它其实是一对一主键关联的一种特殊情况,想要实现双向的关联就必须在映射文件的两端同时配置<one-to-o

【Hibernate步步为营】--双向关联一对一映射详解(一)

摘要:本文以我自己设计植物大战僵尸碰撞检测算法为例进行分析,浅谈游戏开发中碰撞检测算法.本文所提及的碰撞算法与数据结构也可应用于跑酷等游戏中. 关键优化技术1:只检测逻辑上可能存在碰撞关系的物体.比如植物大战僵尸中,植物发射的子弹只能打击其所在行的僵尸,因此子弹只需遍历检测本行的僵尸,而不是存在场景中的全部僵尸.对于地铁跑酷,奔牛跑酷,吃金币的碰撞检测算法亦是如此. 关键优化技术2:子弹检测碰撞僵尸,或是僵尸检测碰撞子弹,谁检测谁碰撞谁的问题,这个可能跟具体项目息息相关.可以从算法效率,以及设计

【Hibernate步步为营】--关联映射之多对一

上篇文章讨论了Hibernate的基本映射,一个实体类对应着一张表,在相应的Hibernate Mapping文件中使用<class>标签映射.并且实体类中的普通属性对应着表字段,使用<property>标签映射.另外在构造实体类时应注意:在实体类中应实现无参的默认的构造函数,提供一个标示,建议不要使用final修饰实体类,为实体类生成getter和setter方法,最后介绍了几种主要的主键生成策略,接下来讨论多对一映射. 一.关联映射之多对一 对于多对一关联映射其实很容易理解,在

【Hibernate步步为营】--多对多映射详解

上篇文章详细讨论了一对多映射,在一对多映射中单向的关联映射会有很多问题,所以不建议使用如果非要采用一对多的映射的话可以考虑使用双向关联来优化之间的关系,一对多的映射其实质上是在一的一端使用<many-to-one>标签来标明它们之间的关系,另外还需要在一的一端的对象中使用set标明集合映射. 一.单向多对多 仍然按照前几篇的文章格式来讨论,首先来看对象之间的关系,单向的多对多关系是两个对象之间发生的,比如在人和职位之间,一个人可以有多个职位,而且一个职位也可以由多人来负责,所以它们之间就形成了

【Hibernate步步为营】--双向关联一对一映射具体解释(一)

一对一的映射在对象模型中是常常见到的,为了将对象模型转换为关系模型就必须在映射文件里进行配置,上篇文章讨论了一对一映射的单向关联的情况,重点是<one-to-one>标签的使用,须要在映射的主对象中加入该标签,并将该对象的主键设置为foreign这样就实现了主键关联映射.讨论完了单向接下来讨论双向映射. 一.双向主键关联 双向的主键关联事实上是单向一对一主键关联的一种特殊情况.仅仅只是要在关联对象的两端的映射文件里都要进行<one-to-one>的配置.另外还要在主映射的主键一端採

hibernate(六)一对一映射

关系映射是指对象之间的关系,并不是指数据库的关系,关系映射是解决当对象处于以下关系之一时,数据库表该如何映射的问题 (一)一对一单向外键关联 1.注解方式配置 创建一个Husband类和Wife类 Husband类:(getWife方法上加注解OneToOne) package cn.orlion.hibernate.model; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import ja

【Hibernate步步为营】--多对多映射具体解释

上篇文章具体讨论了一对多映射,在一对多映射中单向的关联映射会有非常多问题,所以不建议使用假设非要採用一对多的映射的话能够考虑使用双向关联来优化之间的关系,一对多的映射事实上质上是在一的一端使用<many-to-one>标签来标明它们之间的关系,另外还须要在一的一端的对象中使用set标明集合映射. 一.单向多对多 仍然依照前几篇的文章格式来讨论.首先来看对象之间的关系,单向的多对多关系是两个对象之间发生的,比方在人和职位之间,一个人能够有多个职位,并且一个职位也能够由多人来负责,所以它们之间就形

【Hibernate步步为营】--(一对多映射)之双向关联

上篇文章讨论了单向关联的一对多映射,在一的一端维护双向的关系这样的做法尽管能实现可是存在非常多缺陷,首先生成非常多多余的SQL语句,由于多的一端不维护关系,仅仅有一的一端维护,在进行操作时一的一端会发出多余的update语句:其次,由于多的一端不知道一的一端存在,所以在保存多的一端时假设外键为null值,而且在设计数据库时关系字段设为非空,则将无法保存数据.由于单向关联一对多存在非常多缺点那就没有其他的办法了吗,能够採用双向关联来优化. 一.一对多双向关联 这里继续採用上篇文章的学生和班级作为演

Hibernate(三) 之 映射关系

一.概念: 关系:名词,事物之间相互作用.相互联系的状态. 关联:名词:表示对象(数据库表)之间的关系:动词:将对象(数据库表)之间通过某种方式联系起来. 映射:将一种形式转化为另一种形式,包括关系. 级联:动词,有关系的双方中操作一方,另一方也将采取一些动作. 值类型:对象不具备数据库同一性,属于一个实体实例其持久化状态被嵌入到所拥有的实体的表行中,没有标识符. 实体类型:具有数据库标识符. 二.数据库: 1.关系 2.1.1.一对一.一对多.多对多 2.1.2.如何表示? 外键+索引 2.级