Hibernate的关联映射之1-1关联映射

二、1—1

无论是单向1-1映射关联,还是双休1-1映射关联,都有三种映射策略:基于主键、基于外键、采用连接表。

1、单向1-1映射关联

1.1、基于主键的单向1-1映射关联

对于基于主键的单向1-1关联,基于主键关联的持久化类不能拥有自己的主键生成器策略,它的主键由关联实体来负责生成。

是根据他自己的person属性来获得的。即他通过自身的一个getPerson()方法来获得Person对象。然后通过Person对象中的getID()方法获得id,然后赋值给自身id。这样就可以不需要自己来生成id。

采用基于主键的1-1关联时,应使用<one-to-one.../>元素来映射关联实体,配置<one-to-one.../>元素时需要指定一个name属性。

实例(Person<--IDCard)

Person

[java] view
plain
 copy

print?

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

IDCard:

[java] view
plain
 copy

print?

  1. public class IDCard {
  2. private Integer id;
  3. private String useLife;
  4. public String getUseLife() {
  5. return useLife;
  6. }
  7. public void setUseLife(String useLife) {
  8. this.useLife = useLife;
  9. }
  10. private Person person;
  11. public Integer getId() {
  12. return id;
  13. }
  14. public void setId(Integer id) {
  15. this.id = id;
  16. }
  17. public Person getPerson() {
  18. return person;
  19. }
  20. public void setPerson(Person person) {
  21. this.person = person;
  22. }
  23. }

映射文件:

Person.hbm.xml

[html] view
plain
 copy

print?

  1. <hibernate-mapping package="com.hibernate.domain">
  2. <class name="Person" table="person">
  3. <id name="id" column="personID">
  4. <generator class="native" />
  5. </id>
  6. <property name="name" column="personName" />
  7. </class>
  8. </hibernate-mapping>

IDCard.hbm.xml

[html] view
plain
 copy

print?

  1. <hibernate-mapping package="com.hibernate.domain">
  2. <class name="IDCard" table="idCard">
  3. <id name="id" column="idCardID">
  4. <!-- 基于主键关联时,主键生成策略是foreign,表明根据关联类的主键来生成该实体的主键 -->
  5. <generator class="foreign">
  6. <!-- 指定引用关联实体的属性名  -->
  7. <param name="property">person</param>
  8. </generator>
  9. </id>
  10. <property name="useLife" column="useLife" />
  11. <one-to-one name="person" constrained="true" />
  12. </class>
  13. </hibernate-mapping>

在上面的映射文件中,采用这种关联映射策略是,idCard表作为从表,此时idCard表的主键将没有自己的主键生成策略。他是根据person表中的主键来生成的。同时从表(idCard)里记录的主键将会与主表(person)里的记录保存一致。

IDCard中的id既是主键也是外键。那么idCard表如何通过person表来生成主键的呢?

foreign生成器中有一个元素:property。这个元素代表了该表的外键是从哪一个属性中获得的。通过上面的配置可以发现idCard表的外键是从person属性中获得的。它的外键就是通过person属性中的getId获得id,然后将该id直接赋给id。

使用constrained="true"表明该类对应表和被关联的对象所对应的数据库表之间通过一个外键引用对主键进行约束。

通过上面的配置后,就可以对两个实体进行操作了:

[java] view
plain
 copy

print?

  1. static void add(){
  2. Session  session = null;
  3. Transaction tx = null;
  4. try{
  5. session = HibernateUtil.getSession();
  6. tx = session.beginTransaction();
  7. IDCard idCard = new IDCard();
  8. idCard.setUseLife("10年");
  9. Person person = new Person();
  10. person.setName("chentmt");
  11. idCard.setPerson(person);
  12. session.save(person);
  13. session.save(idCard);
  14. tx.commit();
  15. }finally{
  16. if(session!=null)
  17. session.close();
  18. }
  19. }

1.2、基于外键的单向1-1映射关联

基于外键的关联映射与一般的N-1关联映射没有多大区别,只需要将<many-to-one.../>元素中增加unique="true"属性即可。如下:

[html] view
plain
 copy

print?

  1. <hibernate-mapping package="com.hibernate.domain">
  2. <class name="IDCard" table="idCard">
  3. <id name="id" column="idCardID">
  4. <generator class="native" />
  5. </id>
  6. <property name="useLife" column="useLife" />
  7. <many-to-one name="person" column="personID" unique="true"<span style="color:#ff6666;"> </span>/>
  8. </class>
  9. </hibernate-mapping>

unique="true"代表了idCard表的personid外键列上增加了唯一约束--这样就完成基于外键的单向1-1映射了。

其他的配置文件和持久化类都不需要做修改。

1.3、有连接表的单向1-1映射关联

和上面差不多,只需要在有连接表的N-1关联映射中的<many-to-one.../>元素增加一个unique="true"即可。如下:

[html] view
plain
 copy

print?

  1. <hibernate-mapping package="com.hibernate.domain">
  2. <class name="IDCard" table="idCard">
  3. <id name="id" column="idCardID">
  4. <generator class="native" />
  5. </id>
  6. <property name="useLife" column="useLife" />
  7. <!-- 使用join元素强制使用连接表 -->
  8. <join table="person_idCard">
  9. <key column="idCardID"/>
  10. <many-to-one name="person" column="personID" unique="true"/>
  11. </join>
  12. </class>
  13. </hibernate-mapping>

2、双向1-1关联映射

对于双向的1-1关联需要让两个持久化列都增加引用关联实体的属性,并为该属性提供setter和getter方法。持久化类:如上。

2.1基于主键的双向1-1关联映射

基于主键的双向1-1关联映射同样需要在一端的主键生成器策略使用foreign策略,表明将根据对方的主键来生成自己的主键,本实体不能拥有自己的主键生成策略。另一端需要使用<one-to-one.../>元素用来映射关联实体,否则就变成了单向的。映射文件如下:

Person.hbm.xml

[html] view
plain
 copy

print?

  1. <hibernate-mapping package="com.hibernate.domain">
  2. <class name="Person" table="person">
  3. <id name="id" column="personID">
  4. <generator class="native" />
  5. </id>
  6. <property name="name" column="personName" />
  7. <!-- 映射关联实体 -->
  8. <one-to-one name="idCard" />
  9. </class>
  10. </hibernate-mapping>

IDCard.hbm.xml

[html] view
plain
 copy

print?

  1. <hibernate-mapping package="com.hibernate.domain">
  2. <class name="IDCard" table="idCard">
  3. <id name="id" column="idCardID">
  4. <!-- 基于主键关联时,主键生成策略是foreign,表明根据关联类的主键来生成该实体的主键 -->
  5. <generator class="foreign">
  6. <!-- 指定引用关联实体的属性名  -->
  7. <param name="property">person</param>
  8. </generator>
  9. </id>
  10. <property name="useLife" column="useLife" />
  11. <one-to-one name="person" constrained="true" />
  12. </class>
  13. </hibernate-mapping>

对于操作这个两个实体增加同时。因为可以通过两边来访问,所以这里就演示查询

这里查询分为两种:基于主表查询和基于从表查询

基于主表查询(通过主表查询从表记录)

[java] view
plain
 copy

print?

  1. static void query(int personid){
  2. Session  session = null;
  3. try{
  4. session = HibernateUtil.getSession();
  5. Person person = (Person) session.get(Person.class, personid);
  6. System.out.println("useLife="+person.getIdCard().getUseLife());
  7. }finally{
  8. if(session!=null)
  9. session.close();
  10. }
  11. }

我们知道对于N-1关联查询的时候,系统会产生两条sql查询语句来检索从表对象:一条先查询主表,然后根据外键从从表中获取相对应的记录。但是对于1-1关联时,它并不是产生两条sql语句来查询。而是一条sql语句,通过外连接来连接两张表的。如下

[sql] view
plain
 copy

print?

  1. Hibernate: select person0_.personID as personID1_1_, person0_.personName as personName1_1_, idcard1_.idCardID as idCardID2_0_, idcard1_.useLife as useLife2_0_ from person person0_ left outer join idCard idcard1_ on person0_.personID=idcard1_.idCardID where person0_.personID=?

基于从表查询(通过从表查询主表)

[java] view
plain
 copy

print?

  1. static void query(int personid){
  2. Session  session = null;
  3. try{
  4. session = HibernateUtil.getSession();
  5. IDCard idCard = (IDCard) session.get(IDCard.class, 1);
  6. System.out.println(idCard.getPerson().getName());
  7. }finally{
  8. if(session!=null)
  9. session.close();
  10. }
  11. }

通过从表查询主表与通过主表查询从表又有点不同了。在这里它不再是产生一条sql语句,而是两条。如下:

[sql] view
plain
 copy

print?

  1. Hibernate: select idcard0_.idCardID as idCardID2_0_, idcard0_.useLife as useLife2_0_ from idCard idcard0_ where idcard0_.idCardID=?
  2. Hibernate: select person0_.personID as personID1_1_, person0_.personName as personName1_1_, idcard1_.idCardID as idCardID2_0_, idcard1_.useLife as useLife2_0_ from person person0_ left outer join idCard idcard1_ on person0_.personID=idcard1_.idCardID where person0_.personID=?

它会先查询从表,获取记录,然后再通过外连接方式连接两张表根据personID获取记录。

2.2基于外键的双向1-1关联映射

对于基于外键的双向1-1关联映射。外键可以存放任意一边。需要存放外键的一端,需要增加<many-to-one../>元素。同时也需要添加unique="true"属性。

对于双向单位1-1关联映射,两个实体原本是处于平等状态的。但是当我们选择一个表来增加外键后,该表就变成了从表,另一个表变成主表。

另一端需要使用<one-to-one../>元素,该元素需要使用name属性指定关联属性名,同时也需要使用property-ref属性来指定引用关联类的属性。property-ref的值是从表中的引用属性。

映射文件如下:

Person.hbm.xml

[html] view
plain
 copy

print?

  1. <hibernate-mapping package="com.hibernate.domain">
  2. <class name="Person" table="person">
  3. <id name="id" column="personID">
  4. <generator class="native" />
  5. </id>
  6. <property name="name" column="personName" />
  7. <!-- 映射关联实体 -->
  8. <one-to-one name="idCard"    property-ref="person"/>
  9. </class>
  10. </hibernate-mapping>

IDCard.hbm.xml

[html] view
plain
 copy

print?

  1. <hibernate-mapping package="com.hibernate.domain">
  2. <class name="IDCard" table="idCard">
  3. <id name="id" column="idCardID">
  4. <generator class="native" />
  5. </id>
  6. <property name="useLife" column="useLife" />
  7. <many-to-one name="person" column="personID" unique="true" />
  8. </class>
  9. </hibernate-mapping>

2.3有连接表的双向1-1关联映射

采用这个方式是非常少的,因为这中情况映射相当复杂,数据模型繁琐,一般不推荐采用这种策略。

双向1-1关联两端都需要使用<join.../>元素指定连接表,<join../>元素的table属性用于指定连接表的表名,所有两端的table属性值应该是一致的。同时两个也需要增加key元素映射连接表的外键列,还需要增加<many-to-one../.>元素映射关联属性,两个<many-to-one.../>元素都需要增加unique="true"属性。注意这里两端的key元素和<many-to-one../>中column的属性值应该是相反的。

同时为了让hibernate在连接表的两个数据列上增加唯一约束,映射文件应该为两个<key.../>元素指定unique="true"。

当使用连接表来建立1-1关联关系时,两个实体应该是绝对的平等,不存在任何的主从约束关系,hibernate映射他们的连接表时,将会选择某一个外键作为连接表的主键--因此两个持久化类的映射文件依然不是完全相同的。映射文件必须在一端的<join.../>元素中指定inverse="true",而另一端则指定option="true"。下面是两个映射文件

Person.hbm.xml

[html] view
plain
 copy

print?

  1. <hibernate-mapping package="com.hibernate.domain">
  2. <class name="Person" table="person">
  3. <id name="id" column="personID">
  4. <generator class="native" />
  5. </id>
  6. <property name="name" column="personName" />
  7. <join table="person_idCard" inverse="true">
  8. <key column="personID" unique="true" />
  9. <many-to-one name="idCard" column="idCardID" unique="true" />
  10. </join>
  11. </class>
  12. </hibernate-mapping>

IDCard.hbm.xml

[html] view
plain
 copy

print?

  1. <hibernate-mapping package="com.hibernate.domain">
  2. <class name="IDCard" table="idCard">
  3. <id name="id" column="idCardID">
  4. <generator class="native" />
  5. </id>
  6. <property name="useLife" column="useLife" />
  7. <join table="person_idCard" optional="true">
  8. <key column="idCardID" unique="true" />
  9. <many-to-one name="person" column="personID" unique="true"></many-to-one>
  10. </join>
  11. </class>
  12. </hibernate-mapping>
时间: 2024-08-28 15:11:07

Hibernate的关联映射之1-1关联映射的相关文章

Hibernate的七种映射关系之七种关联映射(二)

继续上篇博客 七.Hibernate双向一对多关联映射:让多的一端来维护关系. 主要是解决一对多单向关联的缺陷,而不是需求驱动的. 1.在Student.java实体类里添加Classes引用.private Classes classes; 2.Student.hbm.xml里添加many-to-one标签:<many-to-one name="classes" column="classesid"/>.Classes.hbm.xml在例子(六)里的那

Hibernate的七种映射关系之七种关联映射(一)

关联映射就是将关联关系映射到数据库里,在对象模型中就是一个或多个引用. 一.Hibernate多对一关联映射:就是在"多"的一端加外键,指向"一"的一端. 比如多个学生对应一个班级,多个用户对应一个级别等等,都是多对一关系. 1."多"端实体加入引用"一"端实体的变量及getter,setter方法. 比如说多个学生对应一个班级,在学生实体类加入:private Grade grade; 2."多"端配置文

一口一口吃掉Hibernate(五)——一对多单向关联映射

版权声明:本文为博主原创文章,未经博主允许不得转载.如需转载请声明:[转自 http://blog.csdn.net/xiaoxian8023 ] 在上一篇博客<一口一口吃掉Hibernate(四)--多对一单向关联映射>中,介绍了多对一的关联映射,今天就反过来说一下一对多的单向关联映射. 可能有人会对这2篇博客的题目有点混淆不清,跟日常说的关系有点不同.我们日常说的比如父子关系,夫妻关系都是说的双向关系,而现在讨论的则是单向关系,所以也就有了多对一和一对多的说法. 二者的关系其实很简单,只是

HIbernate学习笔记4 之 延迟加载和 关联映射

一.延迟加载 * 在使用hibernate一些方法的查询数据的时候,返回的只是一个空对象(除id外属性都为NULL),并没有真正的查询数据库,而是在使用这个对象时才会触发查询数据库,并将这些数据注入到这个空对象中.这种将查询实际推迟到对象访问的机制就称为 延迟加载. *好处: 可以提升内存资源的使用率,降低对数据库的访问次数. *方法: session.load()   /  query.iterate()  / 关联映射中对关联属性的加载 *注意问题:避免在使用对象之前,提前关闭session

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

[hibernate]之关于一对一单向,双向关联映射 首先我们来看,Hibernate官方对于一对一单向关联的解释: 基于外键关联的单向一对一关联和单向多对一关联几乎是一样的.唯一的不同就是单向一对一关 联中的外键字段具有唯一性约束. ok,那我们也可以这样理解,一对一其实就是多对一关联的特殊形式,我们知道Hibernate的配置方式有两种,分别是Annotations,XML两种配置方式! Annotations的一对一单向关联映射 人(User)和***号(Card) @Entity @Ta

Hibernate ORM框架——续第二章:Hibernate映射关系:单向关联

一:课堂笔记 **********单表映射*************** 1.只有一个实体类映射一个表 2.有一个实体类+ 一个或者多个值类型,合在一起 映射为一个表 **********多表映射*************** 定义:类有多个映射为多个表 **********数据库层面,如ORM无关************** 2个表之间要建立关系?该如何做?有多少种方法 假定有2个表,分别为A,B 3种关系 a)主键关联:A表的主键对应B表的主键,(一对一的关系) 在数据库种如何建立这种关系?

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

[SSH进阶之路]Hibernate基本原理(一) ,小编介绍了Hibernate的基本原理以及它的核心,采用对象化的思维操作关系型数据库. [SSH进阶之路]Hibernate搭建开发环境+简单实例(二),小编搭建了基本Hibernate的开发环境,并做了一个简单实例,对它的基本原理有了一个理性的认识. [SSH进阶之路]Hibernate基本映射(三),我们介绍了Hibernate的基本映射(即对一个实体进行映射)的相关概念,并给大家实现相关实例,比较简单. 这篇博客,我们开始介绍基于基本映

Hibernate中用注解配置一对多双向关联和多对一单向关联

Hibernate中用注解配置一对多双向关联和多对一单向关联 Hibernate提供了Hibernate Annotations扩展包,使用注解完成映射.在Hibernate3.3之前,需单独下载注解开发包 配置持久化类 配置关联关系 下面我们先从多对一单向关联关系讲起,多对一单向关联就是在多的一方植入一的一方的主键作为外键,下面我们先进行初始配置, 在配置的过程中我们会遇到一个问题  就是无论用load还是get都不会出现延迟加载,那么我们应该如何设置为要延迟加载,这样做的好处是可以在用的时候

Hibernate映射(一)——基本映射

对象关系映射(ORM)的基本认识在之前的两篇博客中已有体现了. ORM基础认识 浅谈ORM的映射方案 今天来学习的是Hibernate的对象关系映射. Hibernate的几种映射方式 基本映射 Hibernate中映射的配置在XML中,我们要对object和table进行映射转换,只需要配置XML即可,所以学会使用Hibernate,重点也就在配置文件中的配置. 首先我们从基本映射开始,如下例: 1.User实体类: import java.util.Date; public class Us

Hibernate映射(一)—基本映射

对象关系映射(ORM)已经在前面的博文中介绍了:ORM介绍 本篇博文主要来介绍Hibernate的基本映射 概念 关系:事物之间相互作用.相互联系的状态 关联:将对象(数据库表)之间通过某种方式联系起来 映射:将一种形式转化为另一种形式 基本映射:表与表之间没有任何联系(系统中的字典表) Hibernate提供了几种映射方式 Hibernate基本组件 映射类(User.java):它是描述数据库表的结构,表中的字段被描述成属性,将来就可以实现把表中的记录映射成为该类的对象 映射文件(User.