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

转载 2015年11月17日 20:51:31

上篇博文【SSH进阶之路】Hibernate映射——一对一单向关联映射(五),我们介绍了一对一的单向关联映射,单向是指只能从人(Person)这端加载身份证端(IdCard),但是反过来,不能从身份证端加载人得信息。如图所示:

      

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

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

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

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

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

 

 映射原理

 

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

 

 对象模型

 

           

 

 从上图中可以看出:

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

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

 

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

Person

  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

  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

  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.               
  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

  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>  

生成的表结构

        

 

对比

 

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

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

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

 

下载

 

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

 

 总结

 

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

 

 

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

相关文章推荐

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

上篇博文【SSH进阶之路】Hibernate映射——一对一单向关联映射(五),我们介绍了一对一的单向关联映射,单向是指只能从人(Person)这端加载身份证端(IdCard),但是反过来,不能从身份证...

【SSH进阶之路】Hibernate映射——一对一单向关联映射(五)

两个实体对象之间是一对一的关联映射,即一个对象只能与另外唯一的一个对象相对应。例如:一个人(Person)只有一张身份证(IdCard)。...

【SSH进阶之路】Hibernate映射——一对一单向关联映射(五)

【SSH进阶之路】Hibernate基本原理(一) ,小编介绍了Hibernate的基本原理以及它的核心,采用对象化的思维操作关系型数据库。 【SSH进阶之路】Hibernate搭建开发环境+简...

【SSH进阶之路】【十一】hibernate5 注解映射【3】一对多多对一双向关联

在上两篇文章里,我们详细地分别讲解了一对多和多对一的单向关联配置的具体属性含义,在这一篇文章里,我们完成两者的的整合建立双向关联。 在实际的博客网站中,我们可能需要根据文章读取作者(用户)信息,但肯定...

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

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

Hibernate一对一双向关联映射以及相互引用toString()方法的错误原因

问题引入:首先我们搭建hibernate一对一双向关联关系,在我们建立hibernate一对一双向关联之后不能再toString()方法中相互引入,否则会报StackOverFlowError,也就是...

hibernate之关于一对一单向,双向关联映射

【hibernate】之关于一对一单向,双向关联映射 首先我们来看,Hibernate官方对于一对一单向关联的解释: 基于外键关联的单向一对一关联和单向多对一关联几乎是一样的。唯一...

一对一双向关联映射

  • 2014年10月31日 08:38
  • 34KB
  • 下载

【SSH进阶之路】Hibernate映射——一对多关联映射(七)

一对多关联映射   映射原理         一对多关联映射和多对一关联映射的映射原理是一致的,都是在多的一端加入一个外键,指向一的一端。关联关系都是由多端维护,只是在写映射时发生了变化。   多对一...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:【SSH进阶之路】Hibernate映射——一对一双向关联映射(六)
举报原因:
原因补充:

(最多只允许输入30个字)