关联关系映射

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

回页首

单向 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. 使用ASM获得JAVA类方法参数名

    在Java1.8之后,可以通过反射API java.lang.reflect.Executable.getParameters来获取到方法参数的元信息,(在使用编译器时加上-parameters参数, ...

  2. ubuntu下SVN使用

    一. ubuntu下SVN(命令行客户端)安装:sudo apt-get install subversion 二. 常用命令2. 文件检出:svn checkout 服务器目录 [本地目录] [-- ...

  3. 【Python】分享使用的插件文件链接(实时更新)

    链接:https://pan.baidu.com/s/1o7AgHtw Python工具实时更新.

  4. 【Mac + Appium + Python3.6学习(五)】之常用的Android自动化测试API总结

    Github测试样例地址:https://github.com/appium-boneyard/sample-code/tree/master/sample-code/examples ①定位text ...

  5. 编写Nginx启停服务脚本

    在/etc/init.d/目录下创建脚本 vim /etc/init.d/nginx 编写脚本内容:(其中下面2行需要根据情况自行修改) nginxd=/opt/nginx/sbin/nginx ng ...

  6. Hadoop2的HA安装(high availability):nfs+zookeeper

    前面介绍过hadoop的简单安装和FA安装,在这里将介绍几种hadoop2中HA(高可用性)安装,HA技术使hadoop不再存在单点namenode的故障. 先来第一种:nfs+zookeeper H ...

  7. Chrome浏览器快捷键(收藏!)

  8. MySQL Error: Illegal mix of collations for operation 'concat'

    在使用concat连接字符串时出现错误:MySQL Error: Illegal mix of collations for operation 'concat' 原因:字段操作默认为UTF8的编码, ...

  9. 理解java的 多态

    http://www.cnblogs.com/chenssy/p/3372798.html

  10. Node.js模块 require和 exports

    https://liuzhichao.com/p/1669.html http://www.cnblogs.com/pigtail/archive/2013/01/14/2859555.html