环境搭建:

用户类:

package cn.echo42.domain;

import javax.persistence.*;
import java.util.HashSet;
import java.util.Set; @Entity
@Table(name = "sys_user")
public class User { @Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name="user_id")
private Long userId;
@Column(name="user_name")
private String userName;
@Column(name="age")
private Integer age; /**
* 配置用户到角色的多对多关系
* 配置多对多的映射关系
* 1.声明表关系的配置
* @ManyToMany(targetEntity = Role.class) //多对多
* targetEntity:代表对方的实体类字节码
* 2.配置中间表(包含两个外键)
* @JoinTable
* name : 中间表的名称
* joinColumns:配置当前对象在中间表的外键
* @JoinColumn的数组
* name:外键名
* referencedColumnName:参照的主表的主键名
* inverseJoinColumns:配置对方对象在中间表的外键
*/
@ManyToMany(targetEntity = Role.class,cascade = CascadeType.ALL)
@JoinTable(name = "sys_user_role",
//joinColumns,当前对象在中间表中的外键
joinColumns = {@JoinColumn(name = "sys_user_id",referencedColumnName = "user_id")},
//inverseJoinColumns,对方对象在中间表的外键
inverseJoinColumns = {@JoinColumn(name = "sys_role_id",referencedColumnName = "role_id")}
)
private Set<Role> roles = new HashSet<>(); public Long getUserId() {
return userId;
} public void setUserId(Long userId) {
this.userId = userId;
} public String getUserName() {
return userName;
} public void setUserName(String userName) {
this.userName = userName;
} public Integer getAge() {
return age;
} public void setAge(Integer age) {
this.age = age;
} public Set<Role> getRoles() {
return roles;
} public void setRoles(Set<Role> roles) {
this.roles = roles;
}
}

角色类

package cn.echo42.domain;

import javax.persistence.*;
import java.util.HashSet;
import java.util.Set; @Entity
@Table(name = "sys_role")
public class Role { @Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "role_id")
private Long roleId;
@Column(name = "role_name")
private String roleName; //配置多对多
@ManyToMany(mappedBy = "roles") //配置多表关系
private Set<User> users = new HashSet<>(); public Long getRoleId() {
return roleId;
} public void setRoleId(Long roleId) {
this.roleId = roleId;
} public String getRoleName() {
return roleName;
} public void setRoleName(String roleName) {
this.roleName = roleName;
} public Set<User> getUsers() {
return users;
} public void setUsers(Set<User> users) {
this.users = users;
}
}

注意把JPA配置更改为Create否则报错找不到关联表

测试运行:

    @Test
public void addTest(){
User user = new User();
user.setUserName("用户1"); Role role = new Role();
role.setRoleName("Java全栈工具人"); userRepository.save(user); roleRepository.save(role);
}

虽然用户和角色表都插入了角色,

但是我们的关联表什么也没有

则我们需要像一对多关系一样进行双向插入:

    @Test
public void addTest(){
User user = new User();
user.setUserName("用户1"); Role role = new Role();
role.setRoleName("Java全栈工具人"); user.getRoles().add(role);
role.getUsers().add(user); userRepository.save(user); roleRepository.save(role);
}

但是执行出错:

Caused by: java.sql.SQLIntegrityConstraintViolationException: Duplicate entry '1-1' for key 'sys_user_role.PRIMARY'

主键重复,解决办法还是一样,其中一个实体类放弃维护

多对多放弃维护,被动的一方放弃

再次执行则正常执行:

多对多级联操作:

基本一样:

    @Test
@Transactional
@Rollback(false) // 设置不自动回滚
public void addExecute6(){
Specification<User> userSpecification = (Specification<User>) (root, criteriaQuery, criteriaBuilder) -> {
// 获取比较的属性
Path<Object> user_id = root.get("userId");
// 模糊要求指定参数类型
return criteriaBuilder.equal(user_id, 1);
};
Optional<User> userOptional = userRepository.findOne(userSpecification); User user = userOptional.get(); userRepository.delete(user);
}

【Spring Data JPA】09 多表关系 Part2 多对多关系操作的更多相关文章

  1. Spring Data JPA 实现多表关联查询

    本文地址:https://liuyanzhao.com/6978.html 最近抽出时间来做博客,数据库操作使用的是 JPA,相对比 Mybatis 而言,JPA 单表操作非常方便,增删改查都已经写好 ...

  2. spring data jpa之Auditing 表的创建时间,更新时间自动生成策略

    java实际编程中,几乎每一张表都会有createTime和updateTime字段,spring的优秀之处在于只要用几个注解,就帮我们解决该类问题,具体实现: 1,实体类添加注解: @EntityL ...

  3. Spring Boot:整合Spring Data JPA

    综合概述 JPA是Java Persistence API的简称,是一套Sun官方提出的Java持久化规范.其设计目标主要是为了简化现有的持久化开发工作和整合ORM技术,它为Java开发人员提供了一种 ...

  4. 集成Spring Data JPA

    1.Spring Data JPA简介 Spring Data是一个用于简化数据访问,并支持云服务的开源框 使用完成Spring Data JPA对user表的CRUD操作. 2.步骤 1.创建工程勾 ...

  5. JDBC、ORM、JPA、Spring Data JPA,傻傻分不清楚?一文带你厘清个中曲直,给你个选择SpringDataJPA的理由!

    序言 Spring Data JPA作为Spring Data中对于关系型数据库支持的一种框架技术,属于ORM的一种,通过得当的使用,可以大大简化开发过程中对于数据操作的复杂度. 本文档隶属于< ...

  6. Spring Boot 入门系列(二十七)使用Spring Data JPA 自定义查询如此简单,完全不需要写SQL!

    前面讲了Spring Boot 整合Spring Boot JPA,实现JPA 的增.删.改.查的功能.JPA使用非常简单,只需继承JpaRepository ,无需任何数据访问层和sql语句即可实现 ...

  7. 最近项目中使用Spring data jpa 踩过的坑

    最近在做一个有关OA项目中使用spring data JPA 操作数据库,结果遇到了补个不可思议的麻烦.困惑了好久. 首先看一下问题吧,这就是当时测试“设置角色时,需要首先删除该用户已经拥有的角色时” ...

  8. spring data jpa hibernate jpa 三者之间的关系

    JPA规范与ORM框架之间的关系是怎样的呢? JPA规范本质上就是一种ORM规范,注意不是ORM框架——因为JPA并未提供ORM实现,它只是制订了一些规范,提供了一些编程的API接口,但具体实现则由服 ...

  9. Spring Data JPA 多个实体类表联合视图查询

    Spring Data JPA 查询数据库时,如果两个表有关联,那么就设个外键,在查询的时候用Specification创建Join 查询便可.但是只支持左连接,不支持右连接,虽说左右连接反过来就能实 ...

  10. JPA、Hibernate、Spring data jpa之间的关系,终于明白了

    什么么是JPA? 全称Java Persistence API,可以通过注解或者XML描述[对象-关系表]之间的映射关系,并将实体对象持久化到数据库中. 为我们提供了: 1)ORM映射元数据:JPA支 ...

随机推荐

  1. ts的keyof

    keyof 是 TypeScript 中的一种类型操作符,用于获取一个类型的所有键(属性名)作为联合类型.它的语法如下: type KeysOfType = keyof ObjectType; 其中: ...

  2. 增补博客 第一篇 python 简易带参计算器

    设计一个简易的参数计算器.[输入格式]第一行输入待计算的带变量参数的计算式第二行输入各变量参数的赋值序列[输出格式]输出带变量参数的计算式的计算结果[输入样例]a+ba=1,b=10[输出样例]11 ...

  3. 直播预告|把握转型浪潮下的机会,甄知科技教你保姆级IT服务管理

    近年来,5G.云计算.大数据.物联网.区块链.人工智能等新兴技术不断在企业中协同发展应用,推动着企业的数字化程度逐步加深.自新冠疫情发生以来,企业的远程服务.服务自助等服务需求激增,企业数字化转型需求 ...

  4. Css var 的基础使用

    Css var 语法 var(custom-property-name, value) - custom-property-name 必须 变量必须以 --开头 后面可以是英文.数字连接符,区分大小写 ...

  5. python post or get请求demo

    # python post or get请求demo import requests; import json; headers={ "Content-Type":"ap ...

  6. AGE SORT

    AGE SORT 你有所有城市的人的年齡資料,而且這城市的人們都大於1歲,且都不會活超過100歲.現在你有個簡單的任務以升冪去排序所有的年齡 Input 接下來會有很多筆的資料,每筆資料從輸入n 開始 ...

  7. .NET6 个人博客-推荐文章加载优化

    个人博客-推荐文章加载优化 前言 随着博客文章越来越多,那么推荐的文章也是越来越多,之前推荐文章是只推荐8篇,但是我感觉有点少,然后也是决定加一个加载按钮,也是类似与分页的效果,点击按钮可以继续加载8 ...

  8. NAT类型检测方案

    一.NAT分类 NAT大致有4种类型: 1. Full Cone NAT 完全锥形NAT,所有从同一个内网IP和端口号发送过来的请求都会被映射成同一个外网IP和端口号,并且任何一个外网主机都可以通过这 ...

  9. uniapp+thinkphp5实现微信支付(JSAPI支付)

    前言 统一支付是JSAPI/NATIVE/APP各种支付场景下生成支付订单,返回预支付订单号的接口,目前微信支付所有场景均使用这一接口.下面介绍的是其中JSAPI的支付实现流程与uniapp唤起微信支 ...

  10. Android案例分享,基于瑞芯微RK3568国产平台!

    开发环境说明 Windows开发环境:Windows7 64bit.Windows10 64bit 虚拟机:VMware15.5.5 AndroidSDK编译环境:Ubuntu18.04.4 64bi ...