JPA3--双向与级联操作

【Spring Boot 3】【JPA】一对一双向关联 【Spring Boot 3】【JPA】一对一单向关联》说明了开发Spring Boot应用时如何使用@OneToOne注解处理一对一单向关联关系,本文介绍如何处理一对一双向关联关系。存储一对一关联关系通常使用主从双数据表,其中主表中有外键指向从表,有时也会使用三数据表,即存在一个中间关联关系表。本文基于主从双数据表实现。本文使用级联权限设置,因此主表的增加操作会影响从表,修改和删除操作都不会影响从表,级联权限设置包括:ALL:拥有以下所有权限。PERSIST。 阅读详情

JPA3–双向与级联操作

一 、单向一对多

1.1配置

在一方配置onetomany

@Entity
@Table(name="t_productDir")
public class ProductDir {
    @Id
    @GeneratedValue
    private Long id;
    private String name;

    //配置多方 List/Set
    @OneToMany(fetch = FetchType.LAZY)
    @JoinColumn(name="dir_id")
    @OrderBy("price desc")
    private List<Product> products = new ArrayList<>();

多方配置:

@Entity
@Table(name="t_product")
public class Product {
    @Id
    @GeneratedValue
    private Long id;
    private String name;
1.2保存操作:

不管是先保存一方还是多方,都有额外发送sql ,效率上面比较低,建议使用单向多对一,如果要学习双向 这个也要学习

1.3在使用集合的时候,使用接口 比如List/Set(掌握)

List主要有顺序上面 比如组合就可以使用
Set主要多对多 多对一上面 没有顺序 但是orderby 也可以排序

二、双向多对一或者一对多

2.1配置:
@Entity
public class ProductDir {
  @Id
  @GeneratedValue
  private Long id;
  private String name;
  @OneToMany(mappedBy=”dir”)
  // @JoinColumn(name="dir_id")
  private Set<Product> products = new HashSet<Product>();
  
@Entity
public class Product {
  @Id
  @GeneratedValue
  private Long id;
  private String name;
  @ManyToOne(fetch = FetchType.LAZY) // 实现延迟加载
  @JoinColumn(name = "dir_id")
  private ProductDir dir;
}
2.2保存代码案例:
public void testManytoOne2() throws Exception{
    //保存数据
    Product  product1= new Product();
    product1.setName("华硕飞行堡垒");

    Product product2 = new Product();
    product2.setName("联想拯救者");

    ProductDir dir = new ProductDir();
    dir.setName("笔记本电脑");

    //设置关系
    dir.getProducts().add(product1);
    dir.getProducts().add(product2);

    product1.setDir(dir);
    product2.setDir(dir);

    //保存
    EntityManager entityManager = JpaUtils.getEntityManager();
    entityManager.getTransaction().begin();

    //双向的
    entityManager.persist(dir);
    entityManager.persist(product1);
    entityManager.persist(product2);
    
    entityManager.getTransaction().commit();
    entityManager.close();
2.3级联操作
配置:
级联保存((mappedBy = "dir" 表示将外键的维护交给多方管理,dir表示多方中字段属性名,,cascade = CascadeType.PERSISIT 表示可以使用级联保存,除了PERSISIT,常用的还有ALL ,remove)
@OneToMany(mappedBy = "dir",cascade = CascadeType.PERSISIT)
@Test
public void testCascade() throws Exception{
    //保存数据
    Product  product1= new Product();
    product1.setName("被子");

    Product product2 = new Product();
    product2.setName("枕头");

    ProductDir dir = new ProductDir();
    dir.setName("床上用品");

    //设置关系
    dir.getProducts().add(product1);
    dir.getProducts().add(product2);
    product1.setDir(dir);
    product2.setDir(dir);
    //保存
    EntityManager entityManager = JpaUtils.getEntityManager();
    entityManager.getTransaction().begin();
    //双向的(保存乙方自动保存另外一方想关的)
    entityManager.persist(dir);

    entityManager.getTransaction().commit();
    entityManager.close();

}

级联删除

@OneToMany(mappedBy = "dir",cascade = CascadeType.REOMOVE)
//级联删除:删除一方,然后级联删除多方
@Test
public void testDelete1() throws Exception{

    //删除分类7的时候,把多方也删除
    EntityManager entityManager = JpaUtils.getEntityManager();
    entityManager.getTransaction().begin();
    ProductDir productDir = entityManager.find(ProductDir.class, 1L);

    entityManager.remove(productDir);

    entityManager.getTransaction().commit();
    entityManager.close();

三、单向多对多

3.1配置
用户配置:
@Table(name="t_user")
public class User {

    @Id
    @GeneratedValue
    private Long id;

    private String name;
    
    @ManyToMany(fetch = FetchType.LAZY)
    @JoinTable(name="t_user_role",joinColumns ={@JoinColumn(name="user_id")},inverseJoinColumns = {@JoinColumn(name="role_id")})
    private Set<Role> roles = new HashSet<>();

角色:
@Entity
@Table(name="t_role")
public class Role {
    @Id
    @GeneratedValue
    private Long id;
    private String name;
3.2保存操作
public void testCreat() throws Exception{
        JpaUtil.getEntityManager();
        // 保存2个用户,保存3个角色(5条)
        User user1 = new User();
        user1.setName("猪儿虫");
        User user2 = new User();
        user2.setName("猪八戒");
        Role role1 = new Role();
        role1.setName("司机");
        Role role2 = new Role();
        role2.setName("演员");
        Role role3 = new Role();
        role3.setName("验黄师");
        // 保存中间表:建立用户到角色关系user1(role1,role2),user2(role1,role2,role3)(5条)
        user1.getRoles().add(role1);
        user1.getRoles().add(role2);

        user2.getRoles().add(role1);
        user2.getRoles().add(role2);
        user2.getRoles().add(role3);

        EntityManager entityManager = JpaUtil.getEntityManager();
        entityManager.getTransaction().begin();

        //保存用户
        entityManager.persist(user1);
        entityManager.persist(user2);
        // 保存角色
        entityManager.persist(role1);
        entityManager.persist(role2);
        entityManager.persist(role3);

        entityManager.getTransaction().commit();
        entityManager.close();
    }

四、双向的多对多

4.1配置:
//学生配置
@Entity
@Table(name = "t_student")
public class Student {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    private String name;
    //级联保存的配置
    @ManyToMany(cascade = CascadeType.ALL)
    @JoinTable(name="t_student_teacher",joinColumns = {@JoinColumn(name="stu_id")},inverseJoinColumns ={@JoinColumn(name = "t_id")})
    private Set<Teacher> tset = new HashSet<>();

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Set<Teacher> getTset() {
        return tset;
    }

    public void setTset(Set<Teacher> tset) {
        this.tset = tset;
    }

//老师配置
@Entity
@Table(name="t_teacher")
public class Teacher {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    @JoinColumn(name="t_name")
    private  String name;
    @ManyToMany(cascade = CascadeType.ALL)
    @JoinTable(name="t_student_teacher",joinColumns = {@JoinColumn(name="t_id")},inverseJoinColumns ={@JoinColumn(name = "stu_id")})
    private Set<Student> cont = new HashSet<>();

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Set<Student> getCont() {
        return cont;
    }

    public void setCont(Set<Student> cont) {
        this.cont = cont;
    }
4.2级联操作和其他操作:
 //级联保存操作  需要的配置(@manytomany(cascade = CascadeType.PERSIST))PERSIST 表示只能级联保存,可以有all,remove配置
    @Test
    public void testAdd() throws Exception{
        EntityManager entityManager = JpaUtil.getEntityManager();
        Student student1 = new Student();
        Student student2 = new Student();
        Student student3 = new Student();
        student1.setName("王大锤");
        student2.setName("刘全有");
        student3.setName("张全蛋");
        Teacher teacher1 = new Teacher();
        Teacher teacher2 = new Teacher();
        teacher1.setName("孙悟空");
        teacher2.setName("邱少华");
        student1.getTset().add(teacher1);
        student1.getTset().add(teacher2);
        student2.getTset().add(teacher2);
        student2.getTset().add(teacher1);
        student3.getTset().add(teacher1);
        entityManager.getTransaction().begin();
        entityManager.persist(student1);
        entityManager.persist(student2);
        entityManager.persist(student3);
        entityManager.getTransaction().commit();
    }
 public void testDelete() throws Exception{
        //普通的删除(会删除查找的数据,并且删除Id相关表的关系链接)
        EntityManager entityManager = JpaUtil.getEntityManager();
        Student student = entityManager.find(Student.class, 1L);
        entityManager.getTransaction().begin();
        entityManager.remove(student);
        entityManager.getTransaction().commit();
    }
    //删除student2与teacher2的关联
    @Test
    public void testDelete2() throws Exception{
        EntityManager entityManager = JpaUtil.getEntityManager();
        Student student2 = entityManager.find(Student.class, 2L);
        Teacher teacher = entityManager.find(Teacher.class, 2L);
        entityManager.getTransaction().begin();
        student2.getTset().remove(teacher);
        entityManager.getTransaction().commit();
    }
    //删除student3的所有teacher相关的关系
    @Test
    public void testDelete3() throws Exception{
        EntityManager entityManager = JpaUtil.getEntityManager();
        Student student3 = entityManager.find(Student.class, 3L);
        entityManager.getTransaction().begin();
        student3.getTset().clear();
        entityManager.getTransaction().commit();
    }
    //级联删除
    @Test
    public void testJLdelete() throws Exception{
        //第一步配置级联删除
        EntityManager entityManager = JpaUtil.getEntityManager();
        Student student = entityManager.find(Student.class, 1L);
        entityManager.getTransaction().begin();
        entityManager.remove(student);
        entityManager.getTransaction().commit();

    }

五、Jpa的优化:
常用:
(1)尽量使用单向多对一去代替单向一对多
如果实在要使用双向的配置,尽量的一方放弃管理
(2)常用多对多的配置,中间表会自动产生,jointable
单向和双向
(3)一对一 看成特殊的 多对一 -->基本不用
注意:实在要使用一对一 尽量使用唯一的外键
(4)表字段尽量少,(有缓存),表不要怕多,jpa自动创建好这个关系

【Spring Boot 3】【JPA】一对多双向关联 【Spring Boot 3】【JPA】@OneToMany 实现一对多单向关联和【Spring Boot 3】【JPA】@ManyToOne 实现一对多单向关联中分别介绍了如何使用@OneToMany和@ManyToOne注解处理一对多单向关联关系,本文介绍结合使用@OneToMany和@ManyToOne注解处理一对多双向关联关系,涵盖主从双数据表和带有中间关联关系表的三数据表这两种存储关联关系的实现。本文定义了公司(Company)、工程师(Engineer)、经理(Manager。 阅读详情

相关推荐

Spring-data-jpa的级联增删改查

title: Spring-data-jpa的级联增删改查 date: 2020-03-13 14:14:23 categories: springboot tags: 概述 此文是为了研究jpa级联表之间的增删改查,对这一方面内容进行一个总结 为了方便描述,使用的数据结构比较简单,书店和书,双向一对多的关系,实体如下: 默认情况下:(即不设置cascade属性,不显式使用CascadeType...

yanzx73的博客 1238

使用 Spring Data Jpa 查询出的实体含有List属性的字段时向List添加属性引发的异常

使用SpringBoot+SpringDataJpa框架,又发现了一个Spring Data 容易出错的问题。

quhan97的博客 3602

Jetson AGX Orin 新手避坑:解决‘找不到nvidia-jetpack包’的完整修复指南

本文详细介绍了Jetson AGX Orin设备在安装JetPack开发套件时遇到的'nvidia-jetpack包缺失'问题的完整解决方案。通过分析问题根源、提供分步修复指南以及系统优化建议,帮助开发者快速解决这一常见问题,充分发挥Jetson AGX Orin的边缘计算性能。

weixin_42520909的博客 461

在spring data jpa中使用redis的通用list及entity存储方法

/** * 从redis中获取对象。注意:未进行haskey检测 * * @param e * @param redis * @param KEY * @param KEY_LIST * @param INDEX * @return * @version 1.0 * @since Service

文竹牧场 5547

什么是Merkle树?用“文件柜”类比理解区块链的核心技术

Merkle树是一种用于区块链的数据结构,像一个高效的“文件柜”,用于存储和验证大量交易数据。比特币通过Merkle树将交易哈希组织成树状结构,层层汇总,最终生成一个唯一的根哈希,存储在区块头中。这种设计大幅减少数据存储和验证成本,支持快速校验交易的完整性和存在性。Merkle树通过密码学保证数据不可篡改,广泛应用于比特币、区块链及其他分布式系统。它的优势在于高效、轻量和安全,尤其适合轻节点验证和数据同步。理解Merkle树就像掌握区块链的“索引秘籍”,是Web3世界的关键技术。

在路上的专栏 1192

MIC(Maximal Information Coefficient)最大互信息系数

MIC(Maximal Information Coefficient)最大互信息系数是一种用于衡量两个变量之间相关性的统计量。它扩展了传统的互信息(MI)和条件互信息(CMI)的概念,具有更广泛的应用范围。MIC能够捕获包括功能性和非功能性的广泛的关联,具有普遍性和公平性。普遍性意味着在足够的样本量下,MIC能够捕捉到广泛的相关关系,而不仅仅局限于特定的功能类型;公平性则意味着MIC对不同类型的包含同等噪声的关系给出了相似的分数。需要注意的是,虽然MIC具有很多优点,但它也有一些局限性。

qlkaicx的博客 4605

JPA实体类注解,看这篇就全会了

JPA实体类注解,看这篇就全会了

weixin_42113716的博客 1955

ERDAS 2022与ArcGIS共存安装教程:如何避免端口冲突(详细配置步骤)

本文提供了一份详细的ERDAS 2022与ArcGIS共存安装教程,核心在于解决两者因FlexNet许可证服务器导致的端口冲突问题。通过分步指导,包括检查现有端口占用、修改ERDAS许可证文件端口号、配置防火墙及客户端设置,确保两款专业GIS与遥感软件能在同一系统上稳定运行。

weixin_29279047的博客 253

JPA EntityManager采用原生SQL语句执行后,返回LIst自定义对象的方法

2、返回List类型 3、返回List类型 在此记录一下,避免忘记!

kiss002wk的博客 1638

LLaMA-Factory微调教程2:命令行sft微调

本文介绍了如何使用llama-factory项目在本地运行Qwen2-7B大语言模型进行对话。首先通过llamafactory-cli env查看环境配置,然后使用git lfs下载Qwen2-7B模型。创建配置文件qwen2_7b_instruct.yaml,修改模型路径和模板参数。最后通过llamafactory-cli chat命令启动对话服务,加载模型配置文件和tokenizer,完成环境初始化后即可进行交互式对话。

Cachel Wood的博客 8815

Pytorch入门实战(2)-使用BP神经网络实现MNIST手写数字识别

上一篇:Pytorch入门实战(1) - 实现线性回归 涉及知识点 Pytorch nn.Module的基本使用 Pytorch nn.Linear的基本用法 PytorchVision Transforms的基本使用 Pytorch中DataLoader的基本用法 Pytorch详解NLLLoss和CrossEntropyLoss 如何确定神经网络的层数和隐藏层神经元数量 本文内容 本文将会使用BP神经网络(就是最普通的神经网络)实现一个MNIST手写数据集的实现。话不多说,直接开始。 首先先导入需要的包

iioSnail的博客 6617

7、JPA对象关系-双向多对一(mappedBy比较少用)

JPA对象关系-双向多对一双向多对一(很少用)废话不多数,看下面代码1、实体类定义2、persistence.xml 配置3、单元测试类4、控制台输出5、JPA维护了2个关系6、用`mappedBy`解决双向多对一出现2个关系问题JPA 双向时,也不会级联保存双向多对一,如何手动维护关系?@JoinColumn 双向多对一(很少用) 双向多对一就是 通过A对象可以找到B对象,同理通过B对象可以找到A对象,他们之间互相依赖。 既然他们互相依赖,在JSON序列化或ToString时就会报出栈内存溢出,并且业务

红鹰 611

微信电脑版本不会自动下载图片吗?——没有找到解决方法。——只会默认下载doc等文件,图片不行,需要自己另存为——有什么办法解决吗?

微信电脑版本不会自动下载图片吗?——没有找到解决方法。——只会默认下载doc等文件,图片不行,需要自己另存为——有什么办法解决吗?此外,用户还可以选择将接收到的图片、视频和文件保存到指定的文件夹中。‌用户可以在微信设置中调整这一设置。

qq_15963745的博客 5088

Spring Boot 3.x 批量操作时的级联操作意外触发详解与解决方案

在Spring Boot 3.x应用中,使用JPA进行批量操作时级联操作(Cascade)的意外触发会导致性能下降、数据不一致等问题。本文分析了级联操作的本质及常见类型,列举了批量保存/删除时级联触发的典型场景,包括全量级联保存、删除风暴、双向关联循环等问题。深入剖析了JPA级联处理机制和saveAll的内部实现原理,指出持久化上下文累积是主要原因。提供了启用SQL日志、分析级联配置等诊断方法,并给出精确控制级联类型、分离关联、使用EntityManager手动控制、采用JDBC批量操作等解决方案,特别推荐

深山技术宅的博客 1920

AutoSAR实验视频讲解:相关资料下载

AutoSAR实验视频讲解:闪烁一颗LED实验【相关资料下载】 总目录 为了方便大家自己的实验顺利进行,这里我们准备了一些实验中可能用到的资料供大家使用 介绍 这里主要是三个文件: MyApp_Core.0是我们的用户代码,在工程集成那集将会讲解 McalConfig.arxml就是我们的Mcal导出文件,用于导入到DaVinci中生成代码 CAN.dbc文件是我们的通信矩阵文件 以上几个文件都是简单的配置,不具有实际项目的实用性,大家仅供参考 // 顺便吐槽一句:百度网盘的吃相真的难看 下载连接

雪云飞星的博客 6668

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

JPA中双向@OneToMany级联删除的正确写法(附真实生产环境案例)

掌握JPA中双向@OneToMany级联删除的正确写法,解决实体关联删除失败问题。通过合理配置cascade和orphanRemoval,确保数据一致性,适用于订单与明细等典型场景,避免常见坑点,值得收藏。

PoliSeed的博客 934

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

JPA概要

1JPA概述 JPA(Java Persistence API,Java持久化API),定义了对象-关系映射(ORM)以及实体对象持久化的标准接口。 JPA是JSR-220(EJB3.0)规范的一部分,在JSR-220中规定实体对象(EntityBean)由JPA进行支持。 所以JPA不局限于EJB3.0,而是作为POJO持久化的标准规范,可以脱离容器独立运行,开发和测试更加方便。 ...

weixin_30765475的博客 80

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

【JPA @ManyToMany级联保存全解析】:彻底搞懂双向关联持久化陷阱与最佳实践

掌握JPA的@ManyToMany级联保存核心技巧,解决双向关联持久化失败与数据不一致问题。涵盖实体映射配置、级联策略选择及性能优化要点,避免常见陷阱。适用于权限管理、标签分类等场景,提升开发效率与数据完整性,值得收藏。

CodeNexus的博客 845

【高阶JPA实战指南】:在@OneToMany关系中安全实现级联删除的6个步骤

掌握JPA @OneToMany 级联删除 cascade的正确用法,避免数据不一致与性能问题。通过双向映射、orphanRemoval、事务管理等6个步骤,安全实现关联实体自动删除。适用于订单-明细、用户-地址等场景,提升数据操作效率,值得收藏。

QuickProceed的博客 849

级联保存失效?深入剖析JPA @ManyToMany映射底层机制与正确用法

解决JPA的@ManyToMany级联保存失效难题,深入解析双向映射与中间表机制,涵盖实体管理、级联策略配置及保存顺序优化。掌握正确用法避免数据丢失,提升持久化效率,值得收藏。

StepLens的博客 849

从入门到精通:掌握JPA @ManyToMany级联保存的4个关键步骤

掌握JPA的@ManyToMany级联保存难题,本文详解实体映射、双向关联、级联策略与保存顺序四大关键步骤,适用于权限管理、标签分类等多场景。清晰示例助你高效实现数据同步,避免持久化异常,值得收藏。

VarChat的博客 1020

【高级JPA技巧】:在@ManyToMany中实现安全级联删除的3种权威方案

掌握JPA @ManyToMany 的级联删除难题,本文提供三种安全高效的解决方案。涵盖双向映射、中间实体优化与手动清理策略,避免数据残留与性能瓶颈。适用于复杂业务场景,确保数据一致性,值得收藏。

FastSolve的博客 1045

为什么你的@ManyToMany不保存?深度解读JPA实体状态与级联传播

解决JPA中多对多关联不保存的难题,深入解析实体状态与级联机制。涵盖@ManyToMany级联保存的正确配置、双向关系维护及持久化顺序,避免常见陷阱。掌握核心技巧,提升数据操作可靠性,值得收藏。

QuickProceed的博客 885

jpa中一对多的级联增删改

以Customer表和Contact表为例:新增://一对多增加 @Test public void testPersist() { Customer customer = new Customer(); customer.setName("新客户"); Contact contact = new Contact(); contact.setName("新联系人"); //...

dimples_qian的博客 6876

JPA之级联关系@OneToMany 和 @ManyToMany

JPA之级联关系@OneToMany 和 @ManyToMany 1. 双向@OneToMany @Entity @Table(name = "TEACHER") public class Teacher { @Id @GenericGenerator(name = "jpa-uuid", strategy = "uuid") @GeneratedValue(genera...

XSemperFI的博客 744

彻底搞懂JPA级联删除机制:从@ManyToOne到@OneToMany的4种删除行为分析

掌握JPA级联删除难题,深入解析@OneToMany与@ManyToOne中cascade的4种删除行为。涵盖实体关联场景、CascadeType配置策略及事务管理要点,避免数据残留与异常。原理清晰、案例实用,值得收藏。

FastSolve的博客 762
上一篇: JAPday2
下一篇: JPA-day4 jpql和乐观锁
wangkedada
博客等级 码龄7年 3粉丝 13原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值