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. python语法基础-异常操作-长期维护

    ###############    python-异常的操作  ############### # 异常:python解释器遇到一个错误,会停止程序的执行,并且提示错误信息,这就是异常, # 抛出异 ...

  2. 线程中调用service方法出错

    public class PnFileTGIComputeThread implements Runnable { @Resource private AppUsedService appUsedSe ...

  3. maven中 pom 文件各个标签的作用

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/20 ...

  4. iOS炫酷动画图案、多种选择器、网络测速、滑动卡片效果等源码

    iOS精选源码 对网络进行测速 自实现大标题,配合原生骨架屏demo 简单方便的pickerVIew记录数据 LZPickerView 科技风绘制组件,简单快速"画"出炫酷图案 R ...

  5. python语法基础-函数-递归函数-长期维护

    ###############    递归   ############## # 递归的定义——在一个函数里再调用这个函数本身 # 递归的最大深度——998 # 二分查找算法 # 你观察这个列表,这是 ...

  6. 前端之css引入方式/长度及颜色单位/常用样式

    1.css三种引入方式 <!DOCTYPE html><html><head> <meta charset="UTF-8"> < ...

  7. synchronized互斥锁实例解析

    目录 synchronized互斥锁实例解析 1.互斥锁基础使用:防止多个线程同时访问对象的synchronized方法. 1.1.多个线程调用同一个方法 1.2.多个线程多个锁,升级为类锁 2.线程 ...

  8. SHELL小练习

    1.SHELL编程服务器IP修改脚本 脚本实现动态IP修改: 脚本实现静态IP修改: 实现IP地址输入判断正确性: IP地址修改成功判断&回滚: 2.SHELL编程Tomcat多实例管理脚本( ...

  9. RAM子账户登录DMS对库进行管理

    前言:阿里云账户是个权限很大的账户,有时候为了不让更多的人知道,但是又必须让别人管理里面某个模块的功能的时候,RAM子账户就显得很重要,所以设置子账户的权限就很有必要了,下面简单设置两种权限(dms上 ...

  10. win10安装inventor失败,怎么强力卸载删除注册表并重新安装

    一些搞设计的朋友在win10系统下安装inventor失败或提示已安装,也有时候想重新安装inventor的时候会出现本电脑windows系统已安装inventor,你要是不留意直接安装invento ...