关联关系映射

关联关系映射,是映射关系中比较复杂的一种映射关系,总的说来有一对一、一对多和多对多几种关系。细分起来他们又有单向和双向之分。下面我们逐一介绍一下。

回页首

单向 OneToOne

单向一对一是关联关系映射中最简单的一种,简单地说就是可以从关联的一方去查询另一方,却不能反向查询。我们用下面的例子来举例说明,清单 1 中的 Person 实体类和清单 2 中的 Address 类就是这种单向的一对一关系,我们可以查询一个 Person 的对应的 Address 的内容,但是我们却不能由一个 Address 的值去查询这个值对应的 Person。

清单 1. 单向一对一关系的拥有端
 @Entity
public class Person implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;
private int age;
@OneToOne
private Address address; //   Getters & Setters
}
清单 2. 单向一对一关系的反端
 @Entity
public class Address implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String street;
private String city;
private String country;
// Gettes& Setters
}
图 1. 单向一对一关系对应的 ER 图

从图 1 他们的 ER 图上可以看出,这种单向的一对一关系在数据库中是以外键的形式被映射的。其中关系的发出端存储一个指向关系的接收端的一个外键。在这个例子中 Person 表中的 ADDRESS_ID 就是指向 address 标的一个外键,缺省情况下这个外键的字段名称,是以它指向的表的名称加下划线“_”加“ID”组成的。当然我们也可以根据我们的喜好来修改这个字段,修改的办法就是使用 @JoinColumn 这个注解。在这个例子中我们可以将这个注解注释在 Person 类中的 Address
属性上去。

回页首

双向 OneToOne

双向关系有一方为关系的拥有端,另一方是关系的反端,也就是“Inverse”端。在这里例子中 Person 拥有这个关系,而 Address 就是关系的“Inverse”端。Address 中我们定义了一个 person 属性,在这个属性上我们使用了 @OneToOne 注解并且定义了他的“mappedBy”属性,这个在双向关系的“Inverse”端是必需的,在下面将要介绍的双向关系中也要用到这个属性。

清单 3. 双向一对一关系中的接受端
 @Entity
public class Address implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String street;
private String city;
private String country;
@OneToOne(mappedBy = "address")
private Person person;
// Gettes& Setters }

回页首

单向 OneToMany

单向关系的一对多我们可以用清单 4 和清单 5 来说明。在关系的发出端 Person 中我们使用 OneToMany 这个注解对 cellPhones 这个属性进行了注释,cellPhones 中存储的是 CellPhone 的一个 List 对象,JPA 就是用这种方式实现一对多的。

清单 4. 单向一对多关系的发出端
 public class Person implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;
private int age;
@OneToMany
private List<CellPhone> cellPhones;
// Getters and Setters
}
清单 5. 单向一对多关系的接收端
 @Entity
public class CellPhone implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String manufacture;
private String color;
private Long phoneNo;
// Getters and Setters
}
图 2. 单向一对多关系对应的 ER 图

在一对多关联关系映射中,默认是以中间表的方式来映射这种关系的。如在本例中,中间表为 person_cellphone,表的名称为关系的拥有端和 Inverse 端中间用下划线连接。中间表的字两个字段分别为两张表的得表名加下划线“_”加 ID 组成。当然我们也可以改表这种默认的中间表的映射方式,我们可以在关系的拥有端使用 @JoinClolum 来使用外键的方式映射这个关系。

回页首

双向 OneToMany

清单 6. 双向一对多关系的接受端
 @Entity
public class Person implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;
private int age; @OneToMany(mappedBy = "person")
private List<CellPhone> cellPhones;
// Getters and Setters
}
清单 7. 双向一对多关系的发出端
 @Entity
public class CellPhone implements Serializable { private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id; private String manufacture;
private String color;
private Long phoneNo;
@ManyToOne
private Person person;
// Getters and Setters
}
图 3. 双向一对多关系对应的 ER 图

回页首

单向 ManyToMany

多对多关联关系中只能通过中间表的方式进行映射。本例的单向多对多关系如下所示。

在清单 8 中我们使用了 ManyToMany 这个注解来对 Teacher 中的 Students 进行注释,其中 Teacher 就是关系的发出端。而在 Student 中我们并没有作任何定义,这是单向多对多的所要求的。

清单 8. 单向多对多关系的发出端
 @Entity
public class Teacher implements Serializable { private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;
private Boolean gender;
private int age;
private int height;
@ManyToMany
private List<Student> students;
// Getters and Setters
}
清单 9. 单向多对多关系的反端
 @Entity
public class Student implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;
private Boolean gender;
private int age;
private int height;
//Getters and Setters
}
图 4. Teacher 对应得数据库表

图 5. Students 对应得数据库表

图 6. 中间生成表

回页首

双向 ManyToMany

清单 10. 双向多对多关系的拥有端
 @Entity
public class Teacher implements Serializable { private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;
private Boolean gender;
private int age;
private int height;
@ManyToMany
private List<Student> students;
// Getters and Setters
}
清单 11. 双向多对多关系的反端
 @Entity
public class Student implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;
private Boolean gender;
private int age;
private int height;
@ManyToMany(mappedBy = "students")
private List<Teacher> teachers;
//Getters and Setters
}
图 7. 双向多对多关系对应的 ER 图

回页首

总结

关联关系映射,是对象映射关系中相对复杂的一种,但也是用处最多的一种,因为数据中的表不可能都是单独存在,彼此之间必定存在千丝万缕的联系,这也是关系型数据库的特征所在。同样关联关系的映射,也是对象关系映射中的难点,重点,仔细揣摩,也还是很容易理解掌握的。

JPA 对象关系映射之关联关系映射策略的更多相关文章

  1. JPA 对象关系映射总结(一)---persistence.xml 文件配置要点

    1. <property name="hibernate.hbm2ddl.auto" value="update"/>,这里表示的 功能是: 自动创 ...

  2. SSH:Hibernate框架(七种关联关系映射及配置详解)

    概念 基本映射是对一个实体进行映射,关联映射就是处理多个实体之间的关系,将关联关系映射到数据库中,所谓的关联关系在对象模型中有一个或多个引用. 分类 关联关系分为上述七种,但是由于相互之间有各种关系, ...

  3. [原创]java WEB学习笔记81:Hibernate学习之路--- 对象关系映射文件(.hbm.xml):hibernate-mapping 节点,class节点,id节点(主键生成策略),property节点,在hibernate 中 java类型 与sql类型之间的对应关系,Java 时间和日期类型的映射,Java 大对象类型 的 映射 (了解),映射组成关系

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

  4. JPA学习笔记(8)——映射一对多关联关系

    一对多关联关系 本文有很多和多对一是一样的,因此不会写得非常具体. 有看不懂的.能够參考JPA学习笔记(7)--映射多对一关联关系 Order实体类 package com.jpa.helloworl ...

  5. JPA学习(四、JPA_映射关联关系)

    框架学习之JPA(四) JPA是Java Persistence API的简称,中文名Java持久层API,是JDK 5.0注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中 ...

  6. hibernate映射的 关联关系:有 一对多关联关系,一对一关联关系,多对多关联关系,继承关系

    hibernate环境配置:导包.... 单向n-1:单向 n-1 关联只需从 n 的一端可以访问 1 的一端 <many-to-one> 元素来映射组成关系: name: 设定待映射的持 ...

  7. Hibernate基础学习(五)—对象-关系映射(下)

    一.单向n-1 单向n-1关联只需从n的一端可以访问1的一端. 域模型: 从Order到Customer的多对一单向关联.Order类中定义一个Customer属性,而在Customer类不用存放Or ...

  8. Hibernate基础学习(四)—对象-关系映射(上)

    一.映射对象标识符      Java语言按内存地址来识别或区分同一个类的不同对象,而关系数据库按主键值来识别或区分同一个表的不同记录.Hibernate使用对象标识符(OID)来建立内存中的对象和数 ...

  9. 死去活来,而不变质:Domain Model(领域模型) 和 EntityFramework 如何正确进行对象关系映射?

    写在前面 阅读目录: 设计误区 数据库已死 枚举映射 关联映射 后记 在上一篇<一缕阳光:DDD(领域驱动设计)应对具体业务场景,如何聚焦 Domain Model(领域模型)?>博文中, ...

随机推荐

  1. iOS开发25个性能调优技巧

    1. 用ARC管理内存 ARC(Automatic Reference Counting, 自动引用计数)和iOS5一起发布,它避免了最常见的也就是经常是由于我们忘记释放内存所造成的内存泄露.它自动为 ...

  2. 0046 @Transactional注解的几个参数--事务传播控制--事务隔离级别--异常与回滚

    @Transactianal注解有一些属性,见Spring-Framework-Reference Table17.3 Transactional-settings @Transactional(pr ...

  3. SockIOPool

    1. SockIOPool – SockIO池化管理,为上层提供的接口是实例化函数[主要是指定memcached服务器地址,各个机器的权重]:根据key&hashCode获取SockIO-网络 ...

  4. JVM Specification 9th Edition (4) Chapter 4. The class File Format

    Chapter 4. The class File Format Table of Contents 4.1. The ClassFile Structure 4.2. Names 4.2.1. Bi ...

  5. SOCK_RAW编程

    TCP(SOCK_STREAM)和UDP套接口(SOCK_DGRAM)可以满足大部分需求,但要获取底层协议内容就需要原始套接字.相比前两者,SOCK_RAW具有如下优点: 1)使用原始套接字可以读写I ...

  6. hdu1569 方格取数(2) 最大点权独立集=总权和-最小点权覆盖集 (最小点权覆盖集=最小割=最大流)

    /** 转自:http://blog.csdn.net/u011498819/article/details/20772147 题目:hdu1569 方格取数(2) 链接:https://vjudge ...

  7. Intellij IDEA和EclipsE之间的的全面对比

    两个IDE之中我最常用的快捷键: 描述 Eclipse IntelliJ 代码补全 Ctrl+space ctrl+space 打开类或者接口 (两个IDE都支持使用"驼峰字符"前 ...

  8. 安装第三方模块时遇到Python version 2.7 required, which was not found

    ## script to register Python 2.0 or later for use with win32all# and other extensions that require P ...

  9. tomocat解决乱码问题

    使用Tomcat进行JSP开发最头疼的莫过于中文乱码问题了,总结Tomcat乱码问题出现的原因必须明白以下几点: 1.Tomcat一般总是默认使用ISO-8859-1作为字符编码方式的.所以,除非你在 ...

  10. CocosCreate 与 Netty 开发斗地主 (一步一步开发)

    CocosCreate 与  Netty 开发斗地主 开发此教程的目的是为了教会大家基本的使用Netty,通过一个小例子来教会大家制作斗地主游戏服务器,采用WebSocket方式! 目前正在制作阶段, ...