SpringDataJPA实体类关系映射配置方式


Posted in Java/Android onDecember 06, 2021

SpringDataJPA

//FetchType.LAZY:懒加载,加载一个实体时,定义懒加载的属性不会马上从数据库中加载
//FetchType.EAGER:急加载,加载一个实体时,定义急加载的属性会立即从数据库中加载
//cascade = CascadeType.ALL 表示所有情况下均进行关联操作,即save-update和delete
@JsonBackReference   //解决循环引用问题
@JsonIgnoreProperties(value = "order") //解决循环引用问题,order内容大,不加载
//双向映射存在转json无限递归问题 需要注解来处理 推荐使用第二个注解 value值为对方表作映射的变量值

1.单向一对一映射

一方

//教师
  @Id @GeneratedValue(strategy=GenerationType.IDENTITY)
  private int id;
  private String name;
  private long salary;
  @OneToOne 
  @JoinColumn(name="PSPACE_ID") 
  private ParkingSpace parkingSpace;

一方

//停车场
    @Id @GeneratedValue(strategy=GenerationType.IDENTITY)
    private int id;
    private int lot;
    private String location;

总结

添加时候需要先添加@OneToOne的那方,删除也是。

2.双向一对一映射

一方

//人员
  @Id
  @GeneratedValue(strategy=GenerationType.IDENTITY)
  private long id;
  private String name;
  @OneToOne
  @JoinColumn(name="DEPT_ID")
  @JsonIgnoreProperties(value = "person")
  private Department department;

一方

//部门
  @Id
  @GeneratedValue(strategy=GenerationType.IDENTITY)
  private long id;
  private String name;
  @OneToOne(mappedBy="department")
  @JsonIgnoreProperties(value = "department")
  private Person person;

总结

@JsonBackReference   //解决循环引用问题
@JsonIgnoreProperties(value = "order") //解决循环引用问题,order内容大,不加载
//双向映射存在转json无限递归问题 需要注解来处理 推荐使用第二个注解 value值为对方表作映射的变量值

3.单向一对多映射

一方

@Id
    @GeneratedValue
    private Long id;
    @Column(length = 32)
    private String name;
    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)//级联保存、更新、删除、刷新;延迟加载
    @JoinColumn(name = "author_id")//在book表增加一个外键列来实现一对多的单向关联
    private Set<Book> books = new HashSet<Book>();

多方

//单向一对多的情况下  多方不需要加任何关联标识
 @Id
    @GeneratedValue
    private Long id;
    @Column(length=32)
    private String name;

总结

因为是单向的关联,多方不需要加任何的关联标识 只需要在一方添加即可

4.双向一对多映射

一方

@Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id; //主键
    private String name; //姓名
    //描述客户可以有多个订单
    @OneToMany(mappedBy = "customer", cascade = CascadeType.ALL)
    @JsonBackReference
    private Set<Order> order = new HashSet<Order>();

多方

@Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
    private Double money;
    private String receiverInfo; //收货地址
    // 订单与客户关联
    @ManyToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "c_id") //指定外键列  
    @JsonIgnoreProperties(value = "order") //解决循环引用问题,order内容大,不加载
    private Customer customer; //描述订单属于某一个客户

总结

@JsonBackReference   //解决循环引用问题
@JsonIgnoreProperties(value = "order") //解决循环引用问题,order内容大,不加载
//双向映射存在转json无限递归问题 需要注解来处理 推荐使用第二个注解 value值为对方表作映射的变量值

5.单向多对一映射

多方

@GeneratedValue
 @Id
 private Integer id;
 @Column(name="ORDER_NAME")
 private String orderName;
 //映射单向 n-1的关联关系
 //使用@ManyToOne来映射多对一的关联关系
 //使用@JoinColumn 来映射外键
 //可使用 @ManyToOne 的fetch 属性来修改默认的关联属性的加载策略
 @JoinColumn(name="CUSTOMER_ID")  //此外键为一方的主键
 @ManyToOne(fetch=FetchType.EAGER)
 private Customer customer;

一方

//单向多对一的情况下,一方不需要加任何关联标识
    @GeneratedValue(strategy=GenerationType.AUTO)
    @Id
    private Integer id;
    private String lastName;
    private String email;
    private int age;
    private Date createdTime;
    private Date birth;

总结

保存多对一时,建议先保存1的一端,后保存n的一端,这样不会多出额外的update语句。

6.双向多对一映射

多方

@GeneratedValue
 @Id
 private Integer id;
 @Column(name="ORDER_NAME")
 private String orderName;
 //映射单向 n-1的关联关系
 //使用@ManyToOne来映射多对一的关联关系
 //使用@JoinColumn 来映射外键
 //可使用 @ManyToOne 的fetch 属性来修改默认的关联属性的加载策略
 @JoinColumn(name="CUSTOMER_ID")
 @ManyToOne(fetch=FetchType.EAGER)
 @JsonIgnoreProperties(value = {"customer","orders"})
 private Customer customer;

一方

@GeneratedValue(strategy=GenerationType.AUTO)
    @Id
    private Integer id;
    @Column(name="LAST_NAME",length=50,nullable=false)
    private String lastName;
    private String email;
    private int age;
    //定义日期格式
    @Temporal(TemporalType.TIMESTAMP)
    private Date createdTime;
    @Temporal(TemporalType.DATE)
    private Date birth;
    //映射单向1-n的关联关系
    //使用@OneToMany 映射单向1-n的关联关系
    //使用@JoinColumn 来映射外键的名称
    //可以使用@OneToMany 的 fetch 属性来修改加载策略
    //可以使用@OneToMany 的 cascade 属性来修改默认的删除策略
//    @JoinColumn(name="CUSTOMER_ID")
    //一的一端放弃维持关联关系
    @OneToMany(fetch=FetchType.EAGER,cascade={CascadeType.REMOVE},mappedBy="customer")
    @JsonIgnoreProperties(value = "orders")
    private Set<Order> orders = new HashSet<>();

总结

1.必须使用@JsonIgnoreProperties注解来拦截转json时无限递归的问题

2.若是双向 1-n 的关联关系, 执行保存时:

(1)若先保存 n 的一端, 再保存 1 的一端, 默认情况下, 会多出2n 条 UPDATE 语句;

(2)若先保存 1 的一端, 则会多出 n 条 UPDATE 语句。

(3)故在进行双向 1-n 关联关系时, 建议使用 n 的一方来维护关联关系, 而 1 的一方不维护关联系, 这样会有效的减少 SQL 语句(即,N的一端对应的表中使用外键关联1的一端,外键对应1的一端的表主键)

注意:若在 1 的一端的 @OneToMany 中使用 mappedBy 属性, 则 @OneToMany 端就不能再使用 @JoinColumn 属性了。

7.单向多对多映射

多方

@Id
    @GeneratedValue
    private Long id;
    private String name;
    // 表示多对多
    @ManyToMany(cascade = CascadeType.ALL)
    // 中间表的表名
    @JoinTable(name = "t_user_role", joinColumns = {@JoinColumn(name = "user_id")},
            //反转  user这个表的 反面则是 role
            inverseJoinColumns = {@JoinColumn(name = "role_id")})
    private Set<Role> roles = new HashSet<>();

多方

@Id
    @GeneratedValue
    private Long id;
    private String name;

总结

使用 @JoinTable 来映射中间表

1. name 指向中间表的名字

2. joinColumns 映射当前类所在的表在中间表中的外键

2.1 name 指定外键列的列名

2.2 referencedColumnName 指定外键列关联当前表的哪一列

3. inverseJoinColumns 映射关联的类所在中间表的外键

8.双向多对多映射

多方

@Id
    @GeneratedValue
    private Long id;
    private String name;
    // 表示多对多
    @ManyToMany(fetch = FetchType.LAZY,cascade = CascadeType.REMOVE)
    @JoinTable(name="t_user_role",joinColumns={@JoinColumn(name="user_id")},
            inverseJoinColumns ={@JoinColumn(name="role_id")} )
    @JsonIgnoreProperties(value = "users")
    private Set<Role> roles = new HashSet<>()

多方

@Id
    @GeneratedValue
    private Long id;
    private String name;
    @ManyToMany(fetch = FetchType.LAZY,cascade = CascadeType.ALL)
    @JoinTable(name="t_user_role",joinColumns={@JoinColumn(name="role_id")},
            inverseJoinColumns ={@JoinColumn(name="user_id")} )
    @JsonIgnoreProperties(value = "roles")
    private Set<User> users = new HashSet<>();

总结

使用 @JoinTable 来映射中间表

1. name 指向中间表的名字

2. joinColumns 映射当前类所在的表在中间表中的外键

2.1 name 指定外键列的列名

2.2 referencedColumnName 指定外键列关联当前表的哪一列

3. inverseJoinColumns 映射关联的类所在中间表的外键

@JsonBackReference //解决循环引用问题
@JsonIgnoreProperties(value = "order") //解决循环引用问题,order内容大,不加载

双向映射存在转json无限递归问题 需要注解来处理 推荐使用第二个注解 value值为对方表作映射的变量值

以上为个人经验,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Java/Android 相关文章推荐
Java方法重载和方法重写的区别到底在哪?
Jun 11 Java/Android
Java SSH 秘钥连接mysql数据库的方法
Jun 28 Java/Android
Java 语言中Object 类和System 类详解
Jul 07 Java/Android
mybatis 获取无数据的字段不显示的问题
Jul 15 Java/Android
Java实现房屋出租系统详解
Oct 05 Java/Android
Spring Security中用JWT退出登录时遇到的坑
Oct 16 Java/Android
OpenCV实现普通阈值
Nov 17 Java/Android
Java中try catch处理异常示例
Dec 06 Java/Android
IDEA 2022 Translation 未知错误 翻译文档失败
Apr 24 Java/Android
Java数据结构之堆(优先队列)
May 20 Java/Android
Java实现注册登录跳转
Jun 16 Java/Android
Java异常处理try catch的基本用法
Dec 06 #Java/Android
Mybatis是这样防止sql注入的
Dec 06 #Java/Android
Java tomcat手动配置servlet详解
Nov 27 #Java/Android
使用jpa之动态插入与修改(重写save)
Nov 23 #Java/Android
Jpa Specification如何实现and和or同时使用查询
Nov 23 #Java/Android
解析mybatis-plus中的resultMap简单使用
Nov 23 #Java/Android
JPA 通过Specification如何实现复杂查询
You might like
最令PHP初学者们头痛的十四个问题
2007/01/15 PHP
利用PHP和AJAX创建RSS聚合器的代码
2007/03/13 PHP
使用PHPMyAdmin修复论坛数据库的图文方法
2012/01/09 PHP
PHP中extract()函数的定义和用法
2012/08/17 PHP
php实现分页工具类分享
2014/01/09 PHP
php将access数据库转换到mysql数据库的方法
2014/12/24 PHP
javascript web页面刷新的方法收集
2009/07/02 Javascript
基于jquery1.4.2的仿flash超炫焦点图播放效果
2010/04/20 Javascript
页面调用单个swf文件,嵌套出多个方法。
2011/11/21 Javascript
JavaScript获取图片真实大小代码实例
2014/09/24 Javascript
常用Javascript函数与原型功能收藏(必看篇)
2016/10/09 Javascript
Vue.js组件tree实现无限级树形菜单
2016/12/02 Javascript
基于MVC方式实现三级联动(JavaScript)
2017/01/23 Javascript
Angular中的$watch、$watchGroup、$watchCollection
2017/06/25 Javascript
mpvue微信小程序多列选择器用法之省份城市选择的实现
2019/03/07 Javascript
浅谈layui使用模板引擎动态渲染元素要注意的问题
2019/09/14 Javascript
[36:09]Secret vs VG 2019国际邀请赛淘汰赛 败者组 BO3 第一场 8.24
2019/09/10 DOTA
用python 批量更改图像尺寸到统一大小的方法
2018/03/31 Python
在VS Code上搭建Python开发环境的方法
2018/04/06 Python
解决python爬虫中有中文的url问题
2018/05/11 Python
Python爬虫框架scrapy实现的文件下载功能示例
2018/08/04 Python
Django 登陆验证码和中间件的实现
2018/08/17 Python
python 异步async库的使用说明
2020/05/04 Python
matplotlib自定义鼠标光标坐标格式的实现
2021/01/08 Python
HTML5实现直播间评论滚动效果的代码
2020/05/27 HTML / CSS
FC-Moto瑞典:欧洲最大的摩托车服装和头盔商店之一
2018/11/27 全球购物
保时捷设计:Porsche Design
2019/03/30 全球购物
办公室保洁员岗位职责
2013/12/02 职场文书
大学生的应聘自我评价
2013/12/13 职场文书
财务工作个人求职的自我评价
2013/12/19 职场文书
毕业横幅标语
2014/10/08 职场文书
教师党的群众路线教育实践活动学习笔记
2014/11/05 职场文书
乒乓球比赛通知
2015/04/27 职场文书
golang 实现Location跳转方式
2021/05/02 Golang
简单聊聊Golang中defer预计算参数
2022/03/25 Golang
PYTHON InceptionV3模型的复现详解
2022/05/06 Python