JPA 关系映射(OneToOne、OneToMany、ManyToMany)

简介: JPA 关系映射(OneToOne、OneToMany、ManyToMany)

单向 OneToOne


  1. 单向一对一是关联关系映射中最简单的一种,简单地说就是可以从关联的一方去查询另一方,却不能反向查询。
  2. @OneToOne注解只用于关系的发出端,同时定义一个接收端类型的字段属性;
  3. 单向的一对一关系在数据库中是以外键的形式被映射的,
  4. 其中关系的发出端存储一个指向关系的接收端的一个外键。
  5. 缺省情况下这个外键的字段名称,是以它指向的表的名称加下划线“_”加“ID”组成的。
  6. 当然我们也可以根据我们的喜好来修改这个字段,修改的办法就是使用 @JoinColumn 这个注解


  • @OneToOne注解
  1. @Target({ElementType.METHOD, ElementType.FIELD})
  2. @Retention(RetentionPolicy.RUNTIME)
  3. public @interface OneToOne {
  4. Class targetEntity() default void.class;
  5. CascadeType[] cascade() default {};
  6. FetchType fetch() default FetchType.EAGER;
  7. boolean optional() default true;
  8. String mappedBy() default "";
  9. boolean orphanRemoval() default false;
  10. }
  11. # targetEntity属性表示默认关联的实体类型,默认为当前标注的实体类;
  12. #cascade属性表示与此实体一对一关联的实体的联级样式类型。联级样式上当对实体进行操作时的策略。
  13. 说明:在定义关系时经常会涉及是否定义Cascade(级联处理)属性,担心造成负面影响.
  14. ·不定义,则对关系表不会产生任何影响
  15. ·CascadeType.PERSIST (级联新建)
  16. ·CascadeType.REMOVE (级联删除)
  17. ·CascadeType.REFRESH (级联刷新)
  18. ·CascadeType.MERGE (级联更新)中选择一个或多个。
  19. ·还有一个选择是使用CascadeType.ALL ,表示选择全部四项
  20. #fetch属性是该实体的加载方式,有两种:LAZYEAGER
  21. #optional属性表示关联的实体是否能够存在null值。默认为true,表示可以存在null值。如果为false,则要同时配合使用@JoinColumn标记。
  22. #mappedBy属性用于双向关联实体时,标注在不保存关系的实体中。
  23. 在四种关联关系
  24. 关联指定列(@JoinColumn
  25. # @JoinColumn用于注释表中的字段,与@Column不同的是它要保存表与表之间关系的字段
  26. # name属性是用来标记表中对应的字段的名称。
  27. 如果不设置name的值,默认情况下,name的取值规则如下:name=关联的表的名称 + "_" + 关联表主键的字段名
  28. # 默认情况下,关联的实体的主键一般用来做外键的。如果不想用主键作为外键,则需要设置referencedColumnName属性,
  29. 如: @JoinColumn(name="address_id", referencedColumnName="ref_id")
  30. # @JoinColumn可以与@OneToOne@ManyToOne@ManyToMany标记同时使用。


双向 OneToOne


  1. 双向关系有一方为关系的发出端,另一方是关系的反端,也就是“Inverse”端(接收端)。

  1. @OneToOne注解,发出端和接收端都要使用,同时定义一个接收端类型的字段属性;
  2. 同时@OneToOne注解中的“mappedBy”属性,这个在双向关系的“Inverse”端是必需的


单向 OneToMany


  1. 单向关系的一对多
  2. @OneToMany 注解只用于关系的发出端(即“一”的一方),
  3. 同时关系的发出端--定义一个集合类型的接收端的字段属性

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

示例

  1. 假设有两个表,订单表和产品表,订单跟产品的关系是一对多的关系,那么在JPA中怎样表示一对多的关系呢?实体关系一对多映射有两种方式:


  • 外键关联
  1. //订单表
  2. @Entity
  3. @Table(name = "orders")
  4. public class Order {
  5. @Id
  6. @GeneratedValue(strategy = GenerationType.AUTO)
  7. private Long id;
  8. @OneToMany(cascade = {CascadeType.ALL})
  9. @JoinColumn(name = "order_id")
  10. private List<Product> productList;
  11. ...
  12. }
  13. //产品表
  14. @Entity
  15. @Table(name = "product")
  16. public class Product {
  17. @Id
  18. @GeneratedValue(strategy = GenerationType.AUTO)
  19. private Long id;
  20. ...
  21. 这样在表product中会增加一列order_id



  • 表关联【默认方式】
  1. /订单表
  2. @Entity
  3. @Table(name = "orders")
  4. public class Order {
  5. @Id
  6. @GeneratedValue(strategy = GenerationType.AUTO)
  7. private Long id;
  8. @OneToMany(cascade = {CascadeType.ALL})
  9. @JoinTable(name = "order_has_product", joinColumns = {@JoinColumn(name = "order_id", referencedColumnName = "id")},inverseJoinColumns = {@JoinColumn(name = "product_id", referencedColumnName = "id")})
  10. private List<Product> productList;
  11. ...
  12. }
  13. joinColumns指定中间表中关联自己ID的字段,inverseJoinColumns表示中间表中关联对方ID的字段
  14. 这样在product表中不会增加任何外键,而是新建了一张order_has_product


双向 OneToMany


  1. 双向一对多关系
  2. @OneToMany(mappedBy='发出端实体名称小写') 注解用于关系的发出端(即“一”的一方),
  3. 同时关系的发出端--定义一个集合类型的接收端的字段属性,
  4. @ManyToOne注解用于关系的接收端端(即“多”的一方),
  5. 同时关系的接收端--定义一个发出端的字段属性,


单向 ManyToMany


  1. 多对多关联关系中只能通过中间表的方式进行映射。
  2. @ManyToMany 注解用于关系的发出端
  3. 同时关系的发出端--定义一个集合类型的接收端的字段属性;
  4. 关系的接收端,不需要做任何定义;


双向 ManyToMany


  1. @ManyToMany 注解用于关系的发出端和接收端
  2. 同时关系的发出端和接收端--定义一个集合类型的接收端的字段属性;
  3. 关系的接收端,@ManyToMany(mappedBy='集合类型发出端实体的字段名称');


参考来源:https://www.ibm.com/developerworks/cn/java/j-lo-jparelated/#icomments



相关文章
最新jsonwebtoken-jjwt 0.12.3 基本使用
最新jsonwebtoken-jjwt 0.12.3 基本使用
4124 1
|
缓存 Java 程序员
Spring中异步注解@Async的使用、原理及使用时可能导致的问题
本文主要介绍了Spring中异步注解的使用、原理及可能碰到的问题,针对每个问题文中也给出了方案。希望通过这篇文章能帮助你彻底掌握`@Async`注解的使用,知其然并知其所以然!
14642 4
|
消息中间件 JSON Java
Spring Boot、Spring Cloud与Spring Cloud Alibaba版本对应关系
Spring Boot、Spring Cloud与Spring Cloud Alibaba版本对应关系
34372 1
|
SQL XML Java
MyBatis-Plus多表关联查询
MyBatis-Plus多表关联查询
2325 0
|
人工智能 自然语言处理 Java
Spring Cloud Alibaba AI 入门与实践
本文将介绍 Spring Cloud Alibaba AI 的基本概念、主要特性和功能,并演示如何完成一个在线聊天和在线画图的 AI 应用。
4025 8
|
存储 Java 数据库连接
@OneToOne注解的作用
@OneToOne注解的作用
|
SQL Java 关系型数据库
JPA 之 QueryDSL-JPA 使用指南2
JPA 之 QueryDSL-JPA 使用指南2
1806 1
|
安全 网络协议
阿里云25端口解封教程完美解决25端口封禁的方法
阿里云出于安全考虑,默认封禁了TCP 25端口出方向的访问流量,所以用户无法使用25号端口邮件服务,云吞铺子分享25端口解封的方法: 阿里云25端口解封申请教程 用户想要使用25端口进行对外连接,可以在安全管控平台中提交25端口解封申请,可以参考官方文档(TCP 25端口解封申请- 阿里云),也可以参考下方云吞铺子的教程: 登录到阿里云管理控制台; 鼠标移动到头像,可以看到下拉菜单,点击“安全管控”如下图: 左侧栏“业务申请”--“25端口解封” 注意:在正式申请前,您需要确认同意并承诺,保证TCP 25端口仅用来连接第三方的SMTP服务器,从第三方的SMTP服务器外发邮件。
27752 1
|
SQL Java 数据库连接
JPA 之 QueryDSL-JPA 使用指南
JPA 之 QueryDSL-JPA 使用指南
1442 0
|
缓存 JavaScript 前端开发
拿下奇怪的前端报错(三):npm install卡住了一个钟- 从原理搞定安装的全链路问题
本文详细分析了 `npm install` 过程中可能出现的卡顿问题及解决方法,包括网络问题、Node.js 版本不兼容、缓存问题、权限问题、包冲突、过时的 npm 版本、系统资源不足和脚本问题等,并提供了相应的解决策略。同时,还介绍了开启全部日志、使用替代工具和使用 Docker 提供 Node 环境等其他处理方法。
13929 2