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

一:主键关联映射

一般一对一主键关联映射通过foreign主键生成器使用另外一个相关联的对象的标识符。通常和<one-to-one>联合起来使用。一对一主键关联映射原理:让两个实体的主键一样,这样就不需要加入多余的字段。此种关联映射有一定的缺点:单向一对一主键关联实际上限制很多,因为你只有IdCard插入了那才能有这个Person.我们看一下具体示例:

根据上面的关系类图,我们再来看一下实体类的定义

实体IdCard.java

public class IdCard  {        private String id;        private int number;        private Person person;  }

实体:Person.java

public class Person  {        private String id;        private String name;        private IdCard idCard;  }

IdCard的配置文件:

<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC  "-//Hibernate/Hibernate Mapping DTD3.0//EN"  "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping>  <classname="com.jzq.hibernate2.IdCard" table="t_IdCard">  <!--这里我们应该注意的是此处的主键生成策略,这里的主键是利用的外键生成策略生成的,这里的主键关联着idcard表中的主键,也就是说,保证Person和idcard的主键相同。  -->       <id name="id">           <generator class="native"/>        </id>        <property name="cardNo"/>  </class> </hibernate-mapping>

person的配置文件:

<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC  "-//Hibernate/Hibernate Mapping DTD3.0//EN"  "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping>  <classname="com.jzq.hibernate2.IdCard" table="t_Person">  <!--id引用外部主键 -->  <id name="id">      <generatorclass="foreign">           <paramname="property">idCard</param>      </generator>  </id>  <property name="name"/>  <one-to-one name="idCard"constrained="true"/>  </class> </hibernate-mapping>

注:one-to-one标签告诉hibernate根据主键加载引用对象 , 把person中的主键拿到idCard表中进行查找,然后把查到的信息加载到引用对象中采用一对一主键约束,那么必须设置constrained属性,表示当前主键作为外键参照了该属性在一对一主键关联映射中默认问级联属性

配置完了以后我们来看一下具体的增删改查操作:

Person person = newPerson();              person.setName("zhangsan");              IdCard idCard = new IdCard();              idCard.setNumber(987654);              person.setIdCard(idCard);              idCard.setPerson(person);              Session session = sessionFactory.openSession();              Transaction tx = null;                     try              {                   tx =session.beginTransaction();                           session.save(person);                   tx.commit();             }             catch(Exception ex)             {                   ex.printStackTrace();                   if(null != tx)                   {                         tx.rollback();                    }             }             finally             {                   session.close();             }            //---------------------------------------------------        //          Session session = sessionFactory.openSession(); //          Transaction tx = null; //          Person person = null; //          try //          { //                tx =session.beginTransaction(); //                person =(Person)session.get(Person.class,"402881ec2ebd7e77012ebd7e79e40001"); //                tx.commit(); //          } //          catch(Exception ex) //          { //                if(null != tx) //                { //                      tx.rollback(); //                } //          } //          finally //          { //                session.close(); //          } //          System.out.println(person.getName()); //          System.out.println(person.getIdCard().getNumber());                        //-----------------------------------------            //          Session session = sessionFactory.openSession(); //          Transaction tx = null; //          //          Person person = null; //          try //          { //                tx =session.beginTransaction(); //                //                person =(Person)session.get(Person.class,"402881ec2ebd7e77012ebd7e79e40001"); //                //                person.setName("lisi");     //                tx.commit(); //          } //          catch(Exception ex) //          { //                if(null != tx) //                { //                      tx.rollback(); //                } //          } //          finally //          { //                session.close(); //          } //          System.out.println(person.getName());                      //-----------------------------------------  //          Session session = sessionFactory.openSession(); //          Transaction tx = null; //          Person person = null; //          try //          { //                tx =session.beginTransaction();   //                person =(Person)session.get(Person.class,"402881ec2ebd7e77012ebd7e79e40001");       //                session.delete(person);                 //                tx.commit(); //          } //          catch(Exception ex) //          { //                if(null != tx) //                { //                      tx.rollback(); //                } //          } //          finally //          { //                session.close(); //          }

通过执行查询,我们可以发现,hibernate的一对一默认执行的检索方式是外连接检索方式,如果我们不想用外连接检索方式,我们可以设置一下one-to-one的fetch属性,他有两个值,一个是select,一个是jion。我想大家通过字面也能猜出他们所对应的检索方式。

Hibernate一对一中也可以设置延迟加载,一对一默认使用的是立即加载,如果需要使用延迟加载,那么需要在one-to-one元素中将constrained属性设为true,并且将待加载的一方的class元素中的lazy属性设为true(或者不去设置,因为该属性默认值就是true)。一对一加载时默认使用左外连接,可以通过修改fetch属性为select修改成每次发送一条select语句的形式。

唯一外键关联映射:其实它是一对多的特殊情况,它基本和一对多是完全相同的,只不过需要配置一个属性而已。其本质上是一对多的蜕化形式。在many-to-one元素中增加unique=”true”属性就变成了一对一。

二、一对唯一外键关联映射——单向

1.一对唯一外键关联映射是多对一关联映射的特例,可以采用<many-to-one>标签,指定多的一端的unique=true,这样就限 制了多的一端的多重性为一,通过这种手段映射一对一唯一外键关联

2.领域模型图:

3.配置

Person.hbm.xml:

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

IDCard.hbm.xml:

<class name="com.bjsxt.hibernate.IdCard"table="t_idcard">  <id name="id">  <generator class="native"/>  </id>  <property name="cardNo"/>  </class>

三、 一对唯一外键关联映射——双向

1.一对一唯一外键关联双向,需要在另一端(idcard),添加<one-to-one>标签,指示hibernate如何加载其关联对象,默认根据主键加载person,外键关联映射中,因为两个实体采用的是person的外键维护的关系,所以不能指定主键加载person,而要根据person的外键加载,所以采用如下映射方式:

<one-to-one name="person"property-ref="idCard"/>

2.领域模型图:

3.具体配置:

Person.hbm.xml:

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

IDCard.hbm.xml

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

转载于:https://blog.51cto.com/javacsh/1129148

Java程序员从笨鸟到菜鸟之(五十八)细谈Hibernate(九)hibernate一对一关系映射...相关推荐

  1. Java程序员从笨鸟到菜鸟之(十)枚举,泛型详解

    一:首先从枚举开始说起 枚举类型是JDK5.0的新特征.Sun引进了一个全新的关键字enum来定义一个枚举类.下面就是一个典型枚举类型的定义: public enum Color{ RED,BLUE, ...

  2. Java程序员从笨鸟到菜鸟全部博客目录

    本文来自:曹胜欢博客专栏.转载请注明出处:http://blog.csdn.NET/csh624366188 欢迎关注微信账号:java那些事:csh624366188.每天一篇java相关的文章 大 ...

  3. Java程序员从笨鸟到菜鸟之(序言)+全部链接

    http://blog.csdn.net/csh624366188 大学上了一年半,接触java也一年半了,虽然中间也有其他东西的学习,但是还是以java为主路线,想想这一年半,除去前半年几乎全玩了, ...

  4. Java程序员由笨鸟到菜鸟 电子版书正式发布 欢迎大家下载

    分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! 欢迎关注 ...

  5. Java程序员从笨鸟到菜鸟之——总结和声明

    前段时间经过大约二十天的时间把javaSE的内容总结了一下,最近由于个人原因和一些乱七八糟的事情,一直没在更新,首先感谢那些一如既往支持我的朋友.最近不知道为什么,一直很懒,做东西也一直是效率很低,生 ...

  6. Java程序员从笨鸟到菜鸟之(五)java开发常用类(包装,数字处理集合等)(下)...

     本文来自:曹胜欢博客专栏.转载请注明出处:http://blog.csdn.net/csh624366188 写在前面:由于前天项目老师建设局的项目快到验收阶段,所以,前天晚上通宵,昨天睡了大半天, ...

  7. Java程序员从笨鸟到菜鸟之(一百零九)一步一步学习webservice(三)开发第一个基于XFire的webservice

    在日常开发中,常用的webservice引擎主要有Axis,axis2,Xfire以及cxf(Xfire的升级版).现在只有axis2和cxf官方有更新.今天我们先以一个比较老的引擎为例.来讲诉一下w ...

  8. Java程序员从笨鸟到菜鸟之(一百零八)一步一步学习webservice(二)webservice基本原理

    本来这第二篇打算讲解"开发第一个基于XFire的webservice"的内容来着.但是想想.开发实例只是局限于了会用的层面上.如果想真正的理解webservice还是需要挖掘其原理 ...

  9. Java程序员从笨鸟到菜鸟之(五)java开发常用类(包装,数字处理集合等)(下)

    写在前面:由于前天项目老师建设局的项目快到验收阶段,所以,前天晚上通宵,昨天睡了大半天,下午我们宿舍聚会,所以时间有点耽误,希望大家见谅 上接: Java程序员从笨鸟到菜鸟之(四)java开发常用类( ...

  10. Java程序员从笨鸟到菜鸟之(一百零六)java操作office和pdf文件(四)页面列表导出cvs,excel、pdf报表.

    在平常的开发中我们常常遇到不仅仅只是导出excel报表的情况.有时候也需要导出pdf或者CSV报表.其实原理都差不多.刚开始本来不打算也这篇博客介绍这个的.感觉这篇博客和前面的博客有点雷同.原理基本都 ...

最新文章

  1. The method replace(int, Fragment) in the type FragmentTransaction is not applicable for the argument
  2. SHAREPOINT爬网设置
  3. Debian8.8解决双系统访问windows磁盘时,有时能成功挂载,有时不能成功挂载的情况...
  4. 数据库常用操作(未完待续)
  5. java中抽象类 接口_java中的抽象类与接口
  6. it招聘的一些门道与招聘数据分析(持续更新)
  7. 狂奔的瑞幸咖啡讲了一个好故事 但还缺失一种 “感觉”
  8. android常用开源库分享
  9. apache poi教程_Apache POI教程
  10. windows server 2003 32位支持8G内存
  11. jquery操作html小技巧
  12. D3/Echarts/G2的对比分析
  13. 请简要概括linux与windows在文件系统方面存在的不同点,简要回答下列与网络操作系统、网络安全和数据存储相关的问题,将解答填入答题纸对应栏内。br 【问题1】(10分)br (a)Win...
  14. 黑马程序员全套Java教程_Java基础入门视频教程零基础自学Java必备教程视频讲义(4)
  15. python图像物体的自动标注_python中matplotlib实现随鼠标滑动自动标注代码实例
  16. 詹姆斯titan_再见,詹姆斯!
  17. 网络传输的两种方式——同步传输和异步传输的区别
  18. HCIE面试备考方法之表达困难症患者请戳
  19. 微信小程序之文字淡入
  20. 信息化 vs 数字化

热门文章

  1. RCE 0day影响数万台QNAP SOHO NAS 设备
  2. 谷歌开源文件访问漏洞审计工具 PathAuditor(详解)
  3. Grafana中文版本 1
  4. 以Chef和Ansible为例快速入门服务器配置
  5. 【DataMagic】如何在万亿级别规模的数据量上使用Spark
  6. 设计模式(十)——代理模式
  7. JS日历控件优化(增加时分秒)
  8. ios上的pvr与png
  9. nagios   IO监控 Error executing iostat command
  10. [NHibernate]使用AttributeNHibernate.Mapping.Attributes