从零开始 Spring Boot 57:JPA中的一对多关系

news/2024/4/20 16:56:24/文章来源:https://blog.csdn.net/hy6533/article/details/131513166

从零开始 Spring Boot 57:JPA中的一对多关系

spring boot

图源:简书 (jianshu.com)

在上篇文章中我们介绍了如何在 JPA 中实现实体的一对一关系,在关系型数据库设计中,除了一对一关系,还存在一对多关系。本篇文章介绍如何在 JPA 中实现一对多关系。

模型

假设我们有两张表,学生表和电子邮件账号表,一个学生可以有多个电子邮件账号,一个电子邮件账号只能对应一个学生,这是典型的一对多关系,用数据库模型可以表示为:

image-20230703103038718

实体

用 JPA 实体实现就是:

@Entity
@Table(name = "user_student")
public class Student {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Long id;@NotNull@NotBlank@Length(max = 45)private String name;private List<Email> emails;
}@Getter
@Entity
@Table(name = "user_email")
public class Email {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Long id;@NotNull@NotBlank@Length(max = 45)private String account;@NotNull@NotBlank@Length(max = 45)private String domain;private Student student;public String toEmailAddress() {return "%s@%s".formatted(this.getAccount(), this.getDomain());}
}

Student实体有一个emails属性,表示一个学生可以拥有多个电子邮件。Email实体有一个student属性,表示一个电子邮件关联到一个学生。

关联关系

下面为这两个实体创建关联关系:

// ...
public class Student {// ...@OneToMany(mappedBy = "student",fetch = FetchType.EAGER,cascade = CascadeType.ALL,orphanRemoval = true)private List<Email> emails;// ...
}// ...
public class Email {// ...@ManyToOne(fetch = FetchType.EAGER)@JoinColumn(name = "student_id")private Student student;// ...
}

方式类似于前一篇文章中介绍的一对一关系的实现,只不过是用@ManyToOne取代@OneToOne。想了解相关注解的详细说明的,可以阅读之前的文章。

值得注意的是,就像一对一关系的那样,一对多关系同样存在着“关系拥有者”和“非拥有者”的区别。显然,在一对多关系中,“关系拥有者”必然是一对多关系的“多”所对应的实体(Email),因为这个实体对应的表(user_email)才真正拥有指向“一”的主键的外键约束(@JoinColumn(name = "student_id"))。

因此,在“关系拥有者”这边,我们需要用@JoinColumn指定外键约束,在关系的另一端(Student),我们需要用@OneToMany(mappedBy='student')指定关系由Email.student属性映射。

其实,“让一条信息能对应多条信息”并不一定要用两张表(实体)来实现,如果不需要对相应的信息进行检索和查询,完全可以在主表上用一个 JSON 格式的字段来保存多条“附加信息”。在 JPA 中可以通过属性转换器来实现,具体的方式可以阅读我的这篇文章。

The End,谢谢阅读。

可以从这里获取本文的完整示例代码。

参考资料

  • 从零开始 Spring Boot 53:JPA 属性转换器 - 红茶的个人站点 (icexmoon.cn)
  • 从零开始 Spring Boot 56:JPA中的一对一关系 - 红茶的个人站点 (icexmoon.cn)
  • Hibernate One to Many Annotation Tutorial | Baeldung

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_325558.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Python】NLP参数控制模板

前言 学过AI的都知道训练一个模型需要调整很多参数&#xff0c;为了有效的管理这些参数、不至于让代码的参数写的乱七八糟&#xff0c;有必要写一套控制参数的模板。 argparser argparser是python当中的参数解析器&#xff0c;在NLP当中主要是用来接受和使用参数的。一个使用它…

QT学习笔记:TCP客户端的实现

QT一般用来做客户端&#xff0c;我这里就简单讲一下怎么开发基于QT的TCP客户端。 1、用QtCreator创建项目 2、界面 3、.pro文件添加network QT core gui network 4、mainwindow.h #ifndef MAINWINDOW_H #define MAINWINDOW_H#include <QMainWindow> #include &l…

SpringBoot的缓存管理

缓存是分布式系统中的重要组件&#xff0c;主要解决数据库数据的高并发访问问题。在实际开发中&#xff0c;尤其是用户 访问量较大的网站&#xff0c;为了提高服务器访问性能、减少数据库的访问压力、提高用户体验&#xff0c;使用缓存显得 尤为重要。Spring Boot对缓存提供了良…

基于单片机的盲人导航智能拐杖老人防丢防摔倒发短息定位

功能介绍 以STM32单片机作为主控系统&#xff1b; OLED液晶当前实时距离&#xff0c;安全距离&#xff0c;当前经纬度信息&#xff1b;超声波检测小于设置的安全距离&#xff0c;蜂鸣器报警提示&#xff1a;低于安全距离&#xff01;超声波检测当前障碍物距离&#xff0c;GPS进…

从零开始备战数学建模国赛之线性规划1.1

从零开始备战数学建模国赛之线性规划1.1 现在距离2023年的数学建模国赛还有不足三个月的时间&#xff0c;想与大家共同备战国赛。 这是我自己总结的一些代码和资料&#xff08;本文中的代码以及参考书籍等&#xff09;&#xff0c;放在github上供大家参考&#xff1a;https://…

Redis学习(一)数据类型、Java中使用redis、缓存概念

文章目录 常用数据结构String类型Hash类型List类型Set类型SortedSet 类型 通用命令key的层级结构 Spring Data Redis快速入门RedisTemplate的序列化方式StringRedisTemplateRedisTemplate的Hash类型操作 实战操作短信登录发送验证码校验登录信息校验登录状态 商家查询缓存缓存更…

怎么学习PHP表单处理与验证? - 易智编译EaseEditing

要学习PHP表单处理与验证&#xff0c;可以按照以下步骤进行&#xff1a; 掌握PHP基础知识&#xff1a; 在学习PHP表单处理与验证之前&#xff0c;首先需要对PHP编程语言有基本的了解。学习PHP的语法、变量、数据类型、数组、函数等基础知识是必要的。 学习HTML表单&#xff1…

MySQL - 第13节 - MySQL用户管理

1.MySQL用户管理概念 MySQL用户管理概念&#xff1a; • 与Linux操作系统类似&#xff0c;MySQL中也有超级用户和普通用户之分。 • 如果一个用户只需要访问MySQL中的某一个数据库&#xff0c;甚至数据库中的某一个表&#xff0c;那么可以为其创建一个普通用户&#xff0c;并为…

交流220v转12v给单片机供电芯片

客户的应用需求&#xff1a;AD220V转DC12V 体积要非常小&#xff0c;单片机使用&#xff0c;单片机设备12V 电流很小不会超过100mA&#xff1f; 【AD220V转DC12V体积小的问题】 问题&#xff1a;我需要将交流电&#xff08;220V&#xff09;转换为直流电&#xff08;12V&…

【CSS】CSS使用变量与变量定义

如何定义可以在CSS中使用的变量 CSS变量&#xff08;也称为自定义属性&#xff09;的定义规则如下&#xff1a; 使用–作为前缀&#xff0c;后跟变量名。变量名可以由字母、数字、连字符和下划线组成&#xff0c;并且不能以连字符开头。变量名区分大小写。变量定义在选择器范…

Arrays类概述,Lambda表达式

数组操作工具类&#xff0c;专门用于操作数组元素 2&#xff1a;常用API Lambda概述 Lambda表达式是JDK开始后的一种新语法形式作用&#xff1a;简化匿名内部类的代码写法 格式&#xff1a; 注意&#xff1a;Lambda表达式只能简化函数式接口的匿名内部类的写法形式。 什么是…

django 使用channels 搭建websocket聊天程序

channels官方文档&#xff1a;Django Channels — Channels 4.0.0 documentation 效果如下&#xff1a; 主要实现功能 基于Django的认证的群聊 具体实现 当建立websocket的时候&#xff0c;建立之前是http消息&#xff0c;我们可以拿到http消息里面的cookie等信息进行认证&…

Elasticsearch实战(二十四)---ES数据建模一对多模型Nested结构

Elasticsearch实战—ES数据建模一对多模型Nested结构 文章目录 Elasticsearch实战---ES数据建模一对多模型Nested结构1.ES 一对多模型Nested 结构模型实战2.ES字段查询2.1 非Nested 错误结构及错误查询2.2 Nested结构&#xff0c;正确查询 3.Nested结构原理 我们如何把Mysql的模…

(0020) H5-Vue-router+Element-ui 搭建非常简单的dashboard

参考学习&#xff1a; Vue Vue-router Element-ui 搭建一个非常简单的dashboard demo demo参考&#xff1a;https://github.com/wangduanduan/vue-el-dashboard 在线预览 效果图&#xff1a; 使用到的技术&#xff1a; Vue Vue-router Element-ui webpack Normalize.css v…

Spring Boot 中的 @RefreshScope 注解是什么,原理,如何使用

Spring Boot 中的 RefreshScope 注解是什么&#xff0c;原理&#xff0c;如何使用 在 Spring Boot 中&#xff0c;RefreshScope 注解是一个非常有用的注解。它可以让 Spring Boot 应用程序在运行时重新加载配置。这意味着您可以在不停止和重新启动应用程序的情况下更改配置。在…

深入理解链表:一种动态的线性数据结构

文章目录 前言1. 概述2. 单向链表3. 单向链表&#xff08;带哨兵&#xff09;4. 双向链表&#xff08;带哨兵&#xff09;5. 环形链表&#xff08;带哨兵&#xff09;6. 结语 前言 链表是我们在日常编程中经常使用的一种数据结构&#xff0c;它相比于数组具有更好的动态性能。…

策略模式深度实践——通用的HTTP接口调用

个人主页&#xff1a;金鳞踏雨 个人简介&#xff1a;大家好&#xff0c;我是金鳞&#xff0c;一个初出茅庐的Java小白 目前状况&#xff1a;22届普通本科毕业生&#xff0c;几经波折了&#xff0c;现在任职于一家国内大型知名日化公司&#xff0c;从事Java开发工作 我的博客&am…

HNU-小学期工训-STC-B案例测试作业

对于一些案例&#xff0c;这里列举一些 流水灯 八位数码管动态扫描 八位数码管流水灯(有BSP版本) 八位数码管滚动显示(有BSP版本) 可变亮度的数码管显示(有BSP版本) 扫描频率可改变的电子钟 按键消抖计数(有BSP版本) 三按键测试(有BSP版本) 霍尔磁场检测(有BSP版本) 数…

kubectl详解之声明式管理方法

目录 一、声明式管理方法二、资源配置清单的管理2.1 查看资源配置清单2.1 修改资源配置清单并应用2.1.1 离线修改2.1.2 在线修改 一、声明式管理方法 适合于对资源的修改操作 声明式资源管理方法依赖于资源配置清单文件对资源进行管理 资源配置清单文件有两种格式&#xff1a;…

【C++11】lambda表达式详解

目录 1.lambda引入 2.语法 3.捕捉列表详解 [ ] 不捕获任何外部变量 [] 捕获父作用域的所有变量的值&#xff0c;只读不可以修改 [&]捕获父作用域的所有变量的引用&#xff0c;可修改捕获的变量 [val] 只捕获指定的变量值&#xff0c;不可以修改 [&val] 只捕获外…