er两个实体之间一定要有关系吗_【你知道吗?】Hibernate/JPA关联关系的单向和双向自动生成的表是不一样滴!!!别再弄错了...

关联关系映射

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

单向 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 图

33aa5bd71c21ef28171dd9d8227cafc9.png

从图 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 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 图

bbc2fa6f6b7402e207cb436c5ccb9635.png

在一对多关联关系映射中,默认是以中间表的方式来映射这种关系的。如在本例中,中间表为 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 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 图

dbbbe56b1632b44c39454cdd77feef01.png

单向 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 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 对应数据库表

a7a09e1c65fc183544512cb936af4c15.png

图 5. Students 对应数据库表

e238c8d89f6ee70b518badba7e39fdbe.png

图 6. 中间生成表

5c682bf65554be5559abebd10a7e3175.png

双向 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 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 teachers; //Getters  and  Setters 
}

图 7. 双向多对多关系对应的 ER 图

e129f753a068f15ff82fcd918e8607b5.png

总结

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


作者:王 汉敏

链接:

https://www.ibm.com/developerworks/cn/java/j-lo-jparelated/index.html

950cbb39c290d8e3dadb3061d101c0ff.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
YOLO高分设计资源源码,详情请查看资源内容中使用说明 YOLO高分设计资源源码,详情请查看资源内容中使用说明 YOLO高分设计资源源码,详情请查看资源内容中使用说明 YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值