文档章节

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

architect刘源源
 architect刘源源
发布于 2018/01/11 19:18
字数 1499
阅读 10
收藏 0

我们介绍了一对一的单向关联映射,单向是指只能从人(Person)这端加载身份证端(IdCard),但是反过来,不能从身份证端加载人得信息。如图所示:

      

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

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

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

 

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

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

 

 映射原理

 

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

 

 对象模型

 

           

 

 从上图中可以看出:

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

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

 

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

Person

[html] view plain copy

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

 IdCard

[java] view plain copy

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

 

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

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

 

分类:

 

主键关联映射

 

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

 

IdCard.hbm.xml

[html] view plain copy

  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,同一对一单向主键关联映射一样

[html] view plain copy

  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.               
  18.             constrained="true"表示,当前主键(person的主键)还是一个外键  
  19.             参照了对端的主键(IdCard的主键),也就是会生成外键约束语句  
  20.          -->  
  21.         <one-to-one name="idCard" class="IdCard" constrained="true"></one-to-one>  
  22.     </class>  
  23. </hibernate-mapping>  

生成的表结构

 

 

唯一外键关联映射

    

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

IdCard.hbm.xml

[html] view plain copy

  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,同一对一单向唯一外键关联映射一样

[html] view plain copy

  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>  

生成的表结构

        

 

对比

 

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

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

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

 

下载

 

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

 

 总结

 

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

 

 

      下篇博文,我们介绍多对多单向关联映射,谢谢关注

© 著作权归作者所有

architect刘源源

architect刘源源

粉丝 169
博文 564
码字总数 941209
作品 0
浦东
程序员
私信 提问
hibernate七种对应关系映射

首先我们了解一个名词ORM,全称是(Object Relational Mapping),即对象关系映射。ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现,这样开发人员就可以把对数据库的...

无敌小学僧
2018/05/17
34
0
Hibernate映射解析——七种映射关系

首先我们了解一个名词ORM,全称是(Object Relational Mapping),即对象关系映射。ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现,这样开发人员就可以把对数据库的...

universeye
2014/05/15
186
0
Java程序员从笨鸟到菜鸟之(五十八)细谈Hibernate(九)hibernate一对一关系映射

一对一关系映射即为关系双方都含有对方一个引用,其实在生活中一对一关系也很常见,比如人和身份证,学生和学号等,都是一对一的关系映射,一对一映射分为单向的和双向的,没种关系映射又可以...

长平狐
2012/11/12
101
0
Hibernate系列——总结篇(九)

概念 Hibernate是一个对象关系映射框架,当然从分层的角度看,我们也说它是数据持久层的框架。 我们从上一句话可以看出Hibernate的核心:面向对象、关系映射以及数据持久化。前面两个概念很容...

architect刘源源
2018/01/11
10
0
【持久化框架】Mybatis与Hibernate的详细对比

前言 这篇博文我们重点分析一下Mybatis与Hibernate的区别,当然在前面的博文中我们已经深入的研究了Mybatis和Hibernate的原理。 Mybatis 【持久化框架】Mybatis简介与原理 【持久化框架】Spr...

sietai
2018/05/18
131
0

没有更多内容

加载失败,请刷新页面

加载更多

Python查询比特币实时价格

在本文中我们将学习如何使用使用coinmarketcap提供的比特币行情API,编写Python程序来获取像比特币、莱特币或以太币之类的区块链数字货币的实时行情/实时价格。 1、比特币行情API调用代码 我...

汇智网教程
18分钟前
2
0
爬虫平台Crawlab核心原理--自动提取字段算法

⚠注意: 可配置爬虫现在仅在Python版本(v0.2.1-v0.2.4)可用,在最新版本Golang版本(v0.3.0)还暂时不可用,后续会加上,请关注近期更新 背景 实际的大型爬虫开发项目中,爬虫工程师会被要...

tikazyq
37分钟前
3
0
postman批量测试

postman批量调用: 先单个调用,成功了 再save为collection 再点击三角形,点击run 设置1000次,run就可以 见《postman批量测试.docx》

Danni3
43分钟前
8
0
js 对象操作 js 对象和对象赋值 去除关联性 对象原型操作 把一个对象A赋值给另一个对象B 并且对象B 修改 不会影响 A对象

当我们在项目需要 复制一个对象到另一个对象并且 被复制的对象不能受复制后的对象的影响。 我先总结下 我们哪些方法可以复制对象 // 直接赋值var obj1 = { a: 1 };var obj2 = obj1;...

xiaogg
44分钟前
7
0
Go微服务全链路跟踪详解

在微服务架构中,调用链是漫长而复杂的,要了解其中的每个环节及其性能,你需要全链路跟踪。 它的原理很简单,你可以在每个请求开始时生成一个唯一的ID,并将其传递到整个调用链。 该ID称为C...

倚天码农
58分钟前
9
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部