1.java和jpa 中所有的关系都是单向的。这个关系数据库不同,关系数据库,通过外键定义并查询,使得反向查询总是存在的。

2.JPA还定义了一个OneToMany关系,它与ManyToMany关系类似,但反向关系(如果已定义)是ManyToOne关系。

OneToMany与JPA中ManyToMany关系的主要区别在于,ManyToMany总是使用中间关系连接表来存储关系,

OneToMany可以使用连接表或者目标对象的表引用中的外键源对象表的主键。

@OneToMany(cascade = CascadeType.ALL)
@JoinColumn(name = "OPR_WARE_SYSCONFIG_ID",foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT))
private List<WarehouseVO> warehouse;

  wareHouseVO的表通过外键字段关联,而定义了OneToMany的属性的VO则不需要添加表字段。

ManyToOne:

@ManyToOne
@JoinColumn(name = "OPR_WAREHOUSE_ENV_ID")
private EnvironmentVO env ;

  

总结,作为many的一方需要有外键关联One的一方。

@ManyToMany 注解

manyToMany需要和@JoinTable表结合使用,ManyToMany总是使用中间关系连接表来存储关系。如果两个Vo都定义了ManyToMany的话,因为单向关系,会生成有2个中间表。所以需要改造成双向关系,使其只存在一个中间表。

例子:

a:一方不需要mappedBy属性,一方需要。

@ManyToMany
@JoinTable(name = "AUTO_SYSTEM", joinColumns = { @JoinColumn(name = "OPR_AUTO_ID") }, inverseJoinColumns = {
@JoinColumn(name = "OPR_SYSTEM_ID") }, foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT), inverseForeignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT))
private List<SystemVO> systems; @ManyToMany(mappedBy = "students")
private List<Service> services;

  

b:

@Entity
public class Student {
@Id
private String id;
@ManyToMany
@JoinTable
private List<Teacher> teachers;
} @Entity
public class Teacher {
@Id
private String id;
@ManyToMany
@JoinTable
private List<Student> students;
}

@ManyToMany即表示了老师和学生的多对多关系。@ManyToMany注解可以用在字段或方法上

但是这样会有两个表出现,TEACHER_STUDENTS表和STUDENT_TEACHERS

原因是这里的多对多关系正是维基百科提到的单向原则。老师和学生虽然分别定义了自己的多对多关系,但这个关系都是单向的,要使关系成为双向。

mappedBy 属性

mappedBy是OneToOne、OneToMany和ManyToMany这三种关联关系的属性。

用来标注拥有这种关系的字段。 除非关系是单向的,否则是必需的。

什么叫拥有关联关系呢,假设是双向一对一的话,那么拥有关系的这一方有建立、解除和更新与另一方关系的能力。而另一方没有,只能被动管理。

由于JoinTableJoinColumn一般定义在拥有关系的这一端,而mappedBy一定是定义在关系的被拥有方(the owned side),也就是跟定义JoinTable

JoinColumn互斥的一方,它的值指向拥有方中关于被拥有方的字段,可能是一个对象(OneToMany),也可能是一个对象集合(ManyToMany)。

@Entity
public class Student {
@Id
private String id;
@ManyToMany(mappedBy = "students")
private List<Teacher> teachers;
} @Entity
public class Teacher {
@Id
private String id;
@ManyToMany
@JoinTable(“student”)
private List<Student> students;
}

  这时中间表只有一张TEACHER_STUDENTS,关联关系也变成了我们想要的双向关系。

Cascade 级联关系

实际业务中,我们通常会遇到以下情况:

  1. 用户和用户的收货地址是一对多关系,当用户被删除时,这个用户的所有收货地址也应该一并删除。
  2. 订单和订单中的商品也是一对多关系,但订单被删除时,订单所关联的商品肯定不能被删除。

此时只要配置正确的级联关系,就能达到想要的效果。

级联关系类型:

  • CascadeType.REFRESH:级联刷新,当多个用户同时作操作一个实体,为了用户取到的数据是实时的,在用实体中的数据之前就可以调用一下refresh()方法
  • CascadeType.REMOVE:级联删除,当调用remove()方法删除Order实体时会先级联删除OrderItem的相关数据
  • CascadeType.MERGE:级联更新,当调用了Merge()方法,如果Order中的数据改变了会相应的更新OrderItem中的数据
  • CascadeType.ALL:包含以上所有级联属性
  • CascadeType.PERSIST:级联保存,当调用了Persist() 方法,会级联保存相应的数据

需要注意的是,CascadeType.ALL要谨慎使用,为了达到数据同步,很多人喜欢用CascadeType.ALL来实现。但上面订单和商品的例子就不适用。

spring jpa ManyToMany 理解和使用的更多相关文章

  1. 使用Spring JPA中Page、Pageable接口和Sort类完成分页排序

    显示时,有三个参数,前两个必填,第几页,一页多少个size,第三个参数默认可以不填. 但是发现这个方法已经过时了,通过查看它的源码发现,新方法为静态方法PageRequest of(page,size ...

  2. 沉淀再出发:Spring的架构理解

    沉淀再出发:Spring的架构理解 一.前言 在Spring之前使用的EJB框架太庞大和重量级了,开发成本很高,由此spring应运而生.关于Spring,学过java的人基本上都会慢慢接触到,并且在 ...

  3. Spring JPA事务

    目录 1. 概述 促进阅读: 2. 配置不带XML的事务 3. 使用XML配置事务 4. @Transactional 注解 5. 潜在的陷阱 5.1. 事务和代理 5.2. 更改隔离级别 5.3. ...

  4. 谈谈对Spring IOC的理解(转)

    学习过Spring框架的人一定都会听过Spring的IoC(控制反转) .DI(依赖注入)这两个概念,对于初学Spring的人来说,总觉得IoC .DI这两个概念是模糊不清的,是很难理解的,今天和大家 ...

  5. 谈谈对Spring IOC的理解

    学习过Spring框架的人一定都会听过Spring的IoC(控制反转) .DI(依赖注入)这两个概念,对于初学Spring的人来说,总觉得IoC .DI这两个概念是模糊不清的,是很难理解的,今天和大家 ...

  6. Spring系列之谈谈对Spring IOC的理解

    学习过Spring框架的人一定都会听过Spring的IoC(控制反转) .DI(依赖注入)这两个概念,对于初学Spring的人来说,总觉得IOC .DI这两个概念是模糊不清的,是很难理解的,今天和大家 ...

  7. spring jpa 实体互相引用返回restful数据循环引用报错的问题

    spring jpa 实体互相引用返回restful数据循环引用报错的问题 Java实体里两个对象有关联关系,互相引用,比如,在一对多的关联关系里 Problem对象,引用了标签列表ProblemLa ...

  8. 谈谈对Spring IOC的理解【转】

    学习过Spring框架的人 一定都会听过Spring的IoC(控制反转) .DI(依赖注入)这两个概念,对于初学Spring的人来说,总觉得IoC .DI这两个概念是模糊不清的,是很难理解的,今天和大 ...

  9. Spring IOC的理解

            学习过Spring框架的人一定都会听过Spring的IoC(控制反转) .DI(依赖注入)这两个概念,对于初学Spring的人来说,总觉得IoC .DI这两个概念是模糊不清的,是很难理 ...

随机推荐

  1. 使用okhttp连接网络,再把数据储存进Sqlite

    这次会把所有之前学过的东西应用在一起,写一个登入的功能. 1. Activity调用CONFIG,获得URL后 2. Activity再调用Okhttp,从服务器返回JSON 3. Activity调 ...

  2. SAP 配置表记录创建人/创建日期/创建时间/更改人/更改日期/更改时间

    在实际开发需求中,为了使客制功能具有灵活的可配置性,通常采用开发功能+配置表的形式处理.有些客制的配置功能需要追溯到谁在什么时候增加了什么配置,或者谁在什么时候更改了什么位置,配置表的Log功能就显得 ...

  3. [Algo] 281. Remove Spaces

    Given a string, remove all leading/trailing/duplicated empty spaces. Assumptions: The given string i ...

  4. Spring Cloud服务消费者(rest+ribbon)

    在上一篇文章,讲了服务的注册和发现.在微服务架构中,业务都会被拆分成一个独立的服务,服务与服务的通讯是基于http restful的.Spring cloud有两种服务调用方式,一种是ribbon+r ...

  5. BGP2

    1) 按照拓扑搭建网络,在所有AS间使用直连接口建立EBGP邻居关系: 2) 在公司总部AS400中,R4与R5,R5与R7,R7与R6,R6与R4间使用环回接口建立IBGP邻居关系,IGP协议使用O ...

  6. python学习笔记(8)迭代器和生成器

    迭代器 迭代是Python最强大的功能之一,是访问集合元素的一种方式. 迭代器是一个可以记住遍历的位置的对象. 迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束.迭代器只能往前不会后退 ...

  7. ospf实验二

    R1,R2,R3为17.1.1.0网段 1. R4先做rip #rip 1 #version 2 #undo sum.. #netwokr 14.0.0.0 实验第四条 标记tag 100 在R4上做 ...

  8. one note使用

    one note 插件及使用 https://sspai.com/post/46957 one note空间大小限制 https://www.jianshu.com/p/5232510fd165

  9. LeetCode Day 1

    目录 1.TwoSum 2.AddTwoNumbers 4.FindMedianSortedArrays 1.TwoSum 给定一个整数数组nums和一个目标值 target,请你在该数组中找出和为目 ...

  10. JAVA数据结构——单链表

    链表:一. 顺序存储结构虽然是一种很有用的存储结构,但是他有如下几点局限性:1. 因为创造线性表的时候已经固定了空间,所以当需要扩充空间时,就需要重新创建一个地址连续的更大的存储空间.并把原有的数据元 ...