关键原因在于对象模型具有方向性:

单向:一端只能加载另一端,不能反过来。

双向:两端都可以加载另一端。

问题来了:如何我们想从身份证端(IdCard)加载人(Person),怎么办呢?

下面我们开始介绍一对一的双向关联映射。

映射原理

双向关联映射与单向关联映射的原理是一样的,双向关联映射并不影响存储,只影响加载。所以,双向关联映射和单向关联映射的关系模型是一样的即数据库的表结构是一样的,只是IdCard的实体类和配置文件(IdCard.hbm.xml)发生了一点点变化。

对象模型

从上图中可以看出:

1、一个人只有一张身份证,唯一的一个身份证号,对象之间是一对一的关系;

2、两个对象得关系维护还是由person端决定(因为关系只能由一端维护主键,否则关系就乱了)。

根据上面的对象模型,我们可以看到Person端没有变化,但是要在IdCard端加上Person的引用,例如Person和IdCard实体类如下。

Person

  1. package com.liang.hibernate;
  2. public class Person {
  3. private int id;
  4. private String name;
  5. private IdCard idCard;
  6. public IdCard getIdCard() {
  7. return idCard;
  8. }
  9. public void setIdCard(IdCard idCard) {
  10. this.idCard = idCard;
  11. }
  12. public int getId() {
  13. return id;
  14. }
  15. public void setId(int id) {
  16. this.id = id;
  17. }
  18. public String getName() {
  19. return name;
  20. }
  21. public void setName(String name) {
  22. this.name = name;
  23. }
  24. }

IdCard

  1. package com.liang.hibernate;
  2. public class IdCard {
  3. private int id;
  4. private String cardNo;
  5. private Person person;
  6. public Person getPerson() {
  7. return person;
  8. }
  9. public void setPerson(Person person) {
  10. this.person = person;
  11. }
  12. public int getId() {
  13. return id;
  14. }
  15. public void setId(int id) {
  16. this.id = id;
  17. }
  18. public String getCardNo() {
  19. return cardNo;
  20. }
  21. public void setCardNo(String cardNo) {
  22. this.cardNo = cardNo;
  23. }
  24. }

无论是单向关联映射还是双向关联映射,他们都属于一对一关联映射,只是他们主键的生成策略不同,分为主键关联映射和唯一外键关联映射。

由于它们都属于一对一关联映射,所以,Hibernate封装双向关联映射时,主键关键映射和唯一外键关联映射的加载策略一样,都采用的是一对一<one-to-one name=""></one-to-one>,只是属性设置不一致,所以,下面我们分开来看IdCard的配置文件。

分类:

主键关联映射

同一对一单向关联映射类似,主键关联即利用主键进行关联,关联主键的值相同。下面我们看一下映射文件:

IdCard.hbm.xml

  1. <?xml version="1.0"?>
  2. <!DOCTYPE hibernate-mapping PUBLIC
  3. "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
  4. "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
  5. <hibernate-mapping package="com.liang.hibernate">
  6. <class name="IdCard" table="t_idCard">
  7. <id name="id">
  8. <generator class="native"></generator>
  9. </id>
  10. <property name="cardNo"></property>
  11. <!-- 怎么加载对象,抓取策略:join联合查询(默认),select:一条条的查询 -->
  12. <one-to-one name="person" class="Person" fetch="join"></one-to-one>
  13. </class>
  14. </hibernate-mapping>

Person.hbm.xml,同一对一单向主键关联映射一样

  1. <?xml version="1.0"?>
  2. <!DOCTYPE hibernate-mapping PUBLIC
  3. "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
  4. "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
  5. <hibernate-mapping package="com.liang.hibernate">
  6. <class name="Person" table="t_person">
  7. <id name="id">
  8. <!-- 采用foreign生成策略,forgeign会取得关联对象的标识 -->
  9. <generator class="foreign" >
  10. <param name="property">idCard</param>
  11. </generator>
  12. </id>
  13. <property name="name"></property>
  14. <!--
  15. one-to-one指示hibernate如何加载其关联对象,默认根据主键加载
  16. 也就是拿到关系字段值,根据对端的主键来加载关联对象
  17. constrained="true"表示,当前主键(person的主键)还是一个外键
  18. 参照了对端的主键(IdCard的主键),也就是会生成外键约束语句
  19. -->
  20. <one-to-one name="idCard" class="IdCard" constrained="true"></one-to-one>
  21. </class>
  22. </hibernate-mapping>

生成的表结构

唯一外键关联映射

一对一双向关联映射的外键关联映射也与一对一单向关联映射的外键关联映射类似,在其一对一的指向端(Person)存在一个唯一外键,该唯一外键与被指向端(IdCard)相关联,关联主键的值相同。下面我们看一下映射文件:

IdCard.hbm.xml

  1. <?xml version="1.0"?>
  2. <!DOCTYPE hibernate-mapping PUBLIC
  3. "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
  4. "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
  5. <hibernate-mapping package="com.liang.hibernate">
  6. <class name="IdCard" table="t_idCard">
  7. <id name="id">
  8. <generator class="native"></generator>
  9. </id>
  10. <property name="cardNo"></property>
  11. <!-- 一对一唯一外键关联双向采用<one-to-one>标签来映射,必须指定<one-to-one>
  12. 标签中的property-ref属性为关系字段的名称
  13. -->
  14. <one-to-one name="person" class="Person" property-ref="idCard"></one-to-one>
  15. </class>
  16. </hibernate-mapping>

Person.hbm.xml,同一对一单向唯一外键关联映射一样

  1. <?xml version="1.0"?>
  2. <!DOCTYPE hibernate-mapping PUBLIC
  3. "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
  4. "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
  5. <hibernate-mapping package="com.liang.hibernate">
  6. <class name="Person" table="t_person">
  7. <id name="id">
  8. <generator class="native" ></generator>
  9. </id>
  10. <property name="name"></property>
  11. <!-- 由于它是一对一的唯一外键关联,它是多对一关联的特例,注释可以直接写成多对一关联-->
  12. <!-- idCard属性,表达的是本对象与IdCard的多对一关系。 -->
  13. <many-to-one name="idCard" class="IdCard" column="idCardId" unique="true"></many-to-one>
  14. </class>
  15. </hibernate-mapping>

生成的表结构

对比

一对一单向和双向关联映射的区别正是对象模型和关系模型的区别之一。

对象模型:有方向性。它到底是单向还是双向是由对象模型决定的即配置文件决定。

关系模型:没有方向性或者说是双向的。从任何一端都可以加载另一端。

下载

以上内容,只证明了一对一双向关联映射不影响存储即没有改变表结构,但不能证明关联是双向的,需要写相应的测试用例,我们以源码的形式给大家。源码下载

总结

一对一双向关联映射并不是必须的,是由需求下决定的。如果没有这样的需求,用户也没有要求,系统也不需要,就没有必要建立双向的关联映射。

Hibernate一对一双向关联映射的更多相关文章

  1. (Hibernate进阶)Hibernate映射——一对一双向关联映射(六)

    上一篇博客我们介绍了一对一的单向关联映射,单向是指只能从人(Person)这端加载身份证端(IdCard),但是反过来,不能从身份证端加载人得信息.如图所示: 关键原因在于对象模型具有方向性: 单向: ...

  2. Hibernate从入门到精通(六)一对一双向关联映射

    在上次的博文Hibernate从入门到精通(五)一对一单向关联映射中我们讲解了一下一对一单向关联映射,这次我们继续讲解一下与之对应的一对一双向关联映射. 一对一双向关联 与一对一单向关联映射所不同的的 ...

  3. Hibernate(六)一对一双向关联映射

    在上次的博文Hibernate从入门到精通(五)一对一单向关联映射中我们讲解了一下一对一单向关联映射, 这次我们继续讲解一下与之对应的一对一双向关联映射. 一对一双向关联 与一对一单向关联映 射所不同 ...

  4. 【SSH系列】hibernate映射 -- 一对一双向关联映射

    开篇前言 上篇博文[SSH进阶之路]hibernate映射--一对一单向关联映射,小编介绍了一对一的单向关联映射,单向是指只能从人(Person)这端加载身份证端(IdCard),但是反过来,不能从身 ...

  5. 【SSH进阶之路】Hibernate映射——一对一双向关联映射(六)

    上篇博文[SSH进阶之路]Hibernate映射--一对一单向关联映射(五),我们介绍了一对一的单向关联映射,单向是指仅仅能从人(Person)这端载入身份证端(IdCard),可是反过来.不能从身份 ...

  6. hibernate一对一单项关联映射

    一.主键关联 1.两个实体对象的主键一样,以表明它们之间的一一对应关系: 2.不需要多余的外键字段来维护关系,仅通过主键来关联,即Person的主键要依赖IdCard的主键,他们共用一个主键值. Pe ...

  7. Hibernate一对一双向关联(外键)

    网站上各种搜索,都是一些清晰或者不清晰的例子,但是用下来一是确实不给力,二是完全不知道所以然. 后来终于在书中查到了就在这里记一下. 首先要说明,这里只解释双向一对一只有一个表里面有外键的情况. 就以 ...

  8. Hibernate一对一双向关联(注解)

    每一个人(Person)对应一个身份证号(IdCard) package cqvie.yjq.domain; import java.util.Date; import javax.persisten ...

  9. Java进阶知识07 Hibernate一对一双向外键关联(Annotation+XML实现)

    1.Annotation 注解版 1.1.创建Husband类和Wife类 package com.shore.model; import javax.persistence.Entity; impo ...

随机推荐

  1. 装饰者模式--《Head First DesignPattern》

    装饰者模式动态地将责任附加到对象杭,若要拓展功能,装设置提供了比继承更有弹性的替代方案. 星巴兹有多种咖啡,它们具有不同的价格.在购买咖啡时,也可以要求在其中加入各种调料,例如豆浆.摩卡.奶泡等等.需 ...

  2. Linux系统调用(转载)

    目录: 1. Linux系统调用原理 2. 系统调用的实现 3. Linux系统调用分类及列表 4.系统调用.用户编程接口(API).系统命令和内核函数的关系 5. Linux系统调用实例 6. Li ...

  3. 微信小程序(原名微信应用号)开发工具0.9版安装教程

    微信小程序全称微信公众平台·小程序,原名微信公众平台·应用号(简称微信应用号) 声明 微信小程序开发工具类似于一个轻量级的IDE集成开发环境,目前仅开放给了少部分受微信官方邀请的人士(据说仅200个名 ...

  4. Activity的启动模式(android:launchMode)

    在android里,有4种activity的启动模式,分别为: “standard” (默认) “singleTop” “singleTask” “singleInstance” 它们主要有如下不同: ...

  5. request对象实现请求转发

    request对象实现请求转发,请求转发指一个web资源收到客户端请求后,通知服务器去调用另外一个web资源进行处理.request对象提供了一个getRequestDispatcher方法,该方法返 ...

  6. Unite Beijing 2015大型活动

    摘要:2015年,我做的最疯狂的事情:网友见面会—去北京参加Unite Beijing 2015大会. 正文:记得,上次在北京参加大型活动还是2008年前–传统电信行业的巅峰时期:那时移动互联网.An ...

  7. TTTAttributedLabel 如何将多个字符串高亮显示

    TTTAttributedLabel进行多个字符串的高亮显示. 需要对每个字符串进行匹配,从而得到所有需要高亮的NSRange,然后利用NSMutableAttributedString对每个NSRa ...

  8. 谈谈css中的before和after

    css中的伪元素before和after,其实有很多小的妙用. 一.基础用法 w3c中的基础用法:用来给元素的内容前面(对应:before)或者后面(对应:after)插入新内容. <p> ...

  9. 【HTML 5或CSS3入门教程】找兼职撰写人才

    出版社要出版一套HTML 5和CSS 3方向的图书,目前急缺两名写作人员,要求1.熟悉CSS 3的各种属性,或熟悉HTML 5框架2.熟悉各种CSS代码,或熟悉各种HTML 5代码3.有写作的兴趣爱好 ...

  10. Java 读写XML文件 API--org.dom4j

    om4j是一个Java的XML API,类似于jdom,用来读写XML文件的.dom4j是一个十分优秀的JavaXML API,具有性能优异.功能强大和极其易使用的特点,同时它也是一个开放源代码的软件 ...