从零开始 Spring Boot 52:@Embedded 和 @Embeddable

news2025/4/3 22:46:43

从零开始 Spring Boot 52:@Embedded 和 @Embeddable

spring boot

图源:简书 (jianshu.com)

这篇文章会介绍@Embedded@Embeddable两个注解在 JPA 中的用法。

简单示例

先看一个示例:

@AllArgsConstructor
@Builder
@Data
@Entity
@Table(name = "user_student")
@Accessors(chain = true)
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
public class Student {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @EqualsAndHashCode.Include
    private Long id;

    @Column(length = 25, nullable = false)
    private String name;

    @Column(length = 50, nullable = false)
    private String address;

    @Column(length = 25)
    private String contactsName;

    @Column(length = 50)
    private String contactsAddress;

    @Column(length = 15)
    private String contactsPhone;

    public Student() {

    }
}

这里使用了 Lombok 相关注解(比如@Builder)帮助构建实体类,详细内容可以阅读我的相关文章。

user_student是一个学生表,其中的contacts_开头的字段保存联系人信息,这体现在实体类中就是以contacts开头的属性。

测试用例:

@Test
@SneakyThrows
void testAddNewStudent() {
    Student newStudent = Student.builder()
        .address("宁安大街101号")
        .name("icexmoon")
        .contactsName("lalala")
        .contactsAddress("北京大街100号")
        .contactsPhone("123456789")
        .build();
    studentRepository.save(newStudent);
    Assertions.assertNotNull(newStudent.getId());
    ObjectMapper om = new ObjectMapper();
    var json = om.writeValueAsString(newStudent);
    System.out.println(json);
}

这样做并没有什么问题,但Student这个实体类并不具备良好的“结构化”,换言之我们很难将其中的联系人部分进行代码重用。

因此,接下来我们要想办法将Student中的联系人部分信息提取出来单独作为一个类型存在,这可以借助 JPA 的@Embedded@Embeddable注解完成。

@Embedded 和 @Embeddable

先定义一个联系人类:

@Embeddable
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class Contacts {
    private String name;
    private String address;
    private String phone;
}

使用@Embedded@Embeddable“改造”Student类:

@AllArgsConstructor
@Builder
@Data
@Entity
@Table(name = "user_student2")
@Accessors(chain = true)
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
public class Student2 {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @EqualsAndHashCode.Include
    private Long id;

    @Column(length = 25, nullable = false)
    private String name;

    @Column(length = 50, nullable = false)
    private String address;

    @Embedded
    @AttributeOverrides({
            @AttributeOverride(name = "name", column = @Column(name = "contacts_name", length = 25)),
            @AttributeOverride(name = "address", column = @Column(name = "contacts_address", length = 50)),
            @AttributeOverride(name = "phone", column = @Column(name = "contacts_phone", length = 15))
    })
    private Contacts contacts;

    public Student2() {

    }
}

这里的@Embeddable注解表明该类可以被“嵌入”到一个实体类中,充当某些字段的映射。@Embedded注解表明这里嵌入了一个用@Embeddable标记的类。

就像以前学习 MyBastis 时在一个 MapperSet 中嵌入另一个 MapperSet 时需要指定字段映射关系,这里同样需要指定,这体现在 @AttributeOverrides注解中包含的多条@AttributeOverride注解。其name属性表示的是被嵌入的类型的属性名称,column属性表示的是对应的数据库表结构中的字段信息。

如果缺省@AttributeOverrides@AttributeOverride注解,默认会用被嵌入的类型(这里是Contacts)的属性名称作为表结构字段名进行映射。但显然这里是行不通的,会报错(因为联系人的姓名与学生的姓名都会映射到同一个name字段)。

现在实体类变得更加“结构化”,这点在测试用例中构建新对象时体现的很明显:

@Test
@SneakyThrows
void testAddNewStudent() {
    Student2 newStudent = Student2.builder()
        .address("宁安大街101号")
        .name("icexmoon")
        .contacts(Contacts.builder()
                  .name("lalala")
                  .address("北京东路100号")
                  .phone("123456789")
                  .build())
        .build();
    student2Repository.save(newStudent);
    Assertions.assertNotNull(newStudent.getId());
    ObjectMapper om = new ObjectMapper();
    var json = om.writeValueAsString(newStudent);
    System.out.println(json);
}

输出的 JSON 串也能更清楚地观察到结构化的好处。

The End,谢谢阅读。

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

参考资料

  • Jpa @Embedded and @Embeddable | Baeldung

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

王益分布式机器学习讲座~Random Notes (1)

0 并行计算是什么?并行计算框架又是什么 并行计算是一种同时使用多个计算资源(如处理器、计算节点)来执行计算任务的方法。通过将计算任务分解为多个子任务,这些子任务可以同时在不同的计算资源上执行,从而实现加速计…

高数基础9

目录 求函数的极值以及曲线的凹项和拐点 例题1 例题2: 例题3: 例题4: 例题5: 例题6: 求渐近线: 例题7 例题8 例题9 例题10: 方程的根 例题11: 零点定理: 罗…

ECharts x轴文本标签全部显示

如果echarts显示标签的时候没有全部显示 代码如下: xAxis: {axisLabel: {interval: 0, //设置文本标签全部显示rotate: 5, //如果内容重叠最好设置一下旋转,就不会重叠了formatter: function(value) { //如果再不行就用formatter自己来截取换行return va…

Echarts折线图设置折线阴影

series中lineStyle添加阴影相关的属性: option {......series: [{......lineStyle: {normal: {width: 4,shadowColor: rgba(0,0,0,1), shadowBlur: 10,shadowOffsetY: 10,shadowOffsetX: 0,......}},......}] };未添加阴影效果: 添加阴影效果&#xf…

F#奇妙游(2):dotnet命令行工具

TUI vs. GUI TUI和GUI分别是文本用户界面(Text User Interface)和图形(Graphic User Interface),是计算机交互界面的两种流派。 最初的时候,神研制了大型机,其输入输出依靠卡带;后…

运动耳机哪款好用推荐、推荐几款专业运动耳机

无论你是健身爱好者、跑步达人还是热衷户外运动的人,一副优秀的运动耳机都是你在运动过程中不可或缺的伴侣。它们不仅能为你提供出色的音质,让你沉浸在动感的节奏中,还能提供稳定舒适的佩戴感,让你忘记耳机存在的同时享受到极致的…

深度学习05-RNN循环神经网络

概述 循环神经网络(Recurrent Neural Network,RNN)是一种具有循环连接的神经网络结构,被广泛应用于自然语言处理、语音识别、时序数据分析等任务中。相较于传统神经网络,RNN的主要特点在于它可以处理序列数据&#xf…

1.1 Metasploit 工具简介

Metasploit 简称(MSF)是一款流行的开源渗透测试框架,由Rapid7公司开发,可以帮助安全和IT专业人士识别安全性问题,验证漏洞的缓解措施,并管理专家驱动的安全性进行评估,提供真正的安全风险情报。…

Nginx HTTPS实践

Nginx HTTPS实践 文章目录 Nginx HTTPS实践1.HTTPS基本概述1.1.为何需要HTTPS1.2.什么是HTTPS1.3.TLS如何实现加密 2.HTTPS实现原理2.1.加密模型-对称加密2.2.加密模型-非对称加密2.3.身份验证机构-CA2.4.HTTPS通讯原理 3.HTTPS扩展知识3.1.HTTPS证书类型3.2.HTTPS购买建议3.3.…

SCTF2023复现(部分web复现)

文章目录 SCTF2023复现webezcheck1nSycServerpypyp? SCTF2023复现 web ezcheck1n find the way to flag.Looks like there are two containers with an evil P in the configuration file of the frontend server 源码&#xff1a; <?php$FLAG "flag{fake_flag}&…

华为OD机试真题 Python 实现【分奖金】【2022Q4 100分】

目录 一、题目描述二、输入描述三、输出描述四、解题思路五、Python算法源码六、效果展示1、输入2、输出 一、题目描述 公司老板做了一笔大生意&#xff0c;想要给每位员工分配一些奖金&#xff0c;想通过游戏的方式来决定每个人分多少钱。按照员工的工号顺序&#xff0c;每个…

《移动互联网技术》 第七章 数据存取: 掌握File、SharePreferences、SQLite和ContentProvider四种数据存取方式

&#x1f337;&#x1f341; 博主 libin9iOak带您 Go to New World.✨&#x1f341; &#x1f984; 个人主页——libin9iOak的博客&#x1f390; &#x1f433; 《面试题大全》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33…

iview button组件点击第一次无效的原因解决

最近在开发页面&#xff0c;发现登陆页老是需要点击两下才能进入具体页面&#xff0c;一开始没在意&#xff0c;但是使用久了&#xff0c;就感觉肯定是问题&#xff0c;于是仔细查看了代码&#xff0c;如上图所示&#xff1a; 一开始我的跳转是放在存储token的上面的&#xff0…

管理类联考——英语——趣味篇——词根词汇——按“认识自然、认识自我、改造自然、情感智力、人与社会”分类”

文章目录 前言第⼀部分、认识⾃然1&#xff0e; ⾃然源于⽣命-bio-“⽣命&#xff0c;⽣物”-nat-“⽣命&#xff0c;出⽣”-gen-&#xff0c;-geo- “⽣&#xff0c;出⽣&#xff0c;⽣发;⼟地”-viv- -vit-, “⽣&#xff0c;⽣命&#xff0c;出⽣”-mort- “死&#xff0c;死…

如何使用企业门户(门户,Portal)平台构建千人千面的企业数字神经网络、门户工作台,集团数字化门户系统?

基于人工智能与AI算法的信创门户“One”&#xff0c;打破了IT系统间信息孤岛。实现了系统间的互联互通&#xff08;数字孪生&#xff0c;塔尖通信&#xff09;&#xff0c;结合机器学习&#xff0c;打造企业数字神经网络&#xff0c;给用户一个千人千面的智慧门户工作台&#x…

【Python】一文带你学会数据结构中的堆、栈

作者主页&#xff1a;爱笑的男孩。的博客_CSDN博客-深度学习,活动,python领域博主爱笑的男孩。擅长深度学习,活动,python,等方面的知识,爱笑的男孩。关注算法,python,计算机视觉,图像处理,深度学习,pytorch,神经网络,opencv领域.https://blog.csdn.net/Code_and516?typeblog个…

移除所有本地应用程序(数据库)加密设置

大家好&#xff0c;才是真的好。 最近我就有这样一个烦恼&#xff0c;要移除Notes本地的所有本地应用程序&#xff08;数据库&#xff09;的加密设置&#xff0c;这样就可以放到Domino服务器上&#xff0c;然后支持其他电脑上不同的Notes访问。毕竟&#xff0c;默认地&#xf…

Open-World Class Discovery with Kernel Networks (ICDM 2020)

Open-World Class Discovery with Kernel Networks (ICDM 2020) 摘要 我们研究了一个开放世界类发现问题&#xff0c;在这个问题中&#xff0c;训练样本是来自旧类有标签的样本&#xff0c;而我们从没有标记的测试样本中发现新的类。解决这一范式有两个关键的挑战:(a)将知识从…

【ESP-IDF】在squareline studio上设计GUI并移植到esp-box上

因为squareline studio软件中适配了ESP-BOX&#xff0c;所以作者本想直接使用该软件创建的工程&#xff0c;但是会出现花屏的现象&#xff0c;也不知道是不是没有做好esp-box-lite的适配。 因此只能先用squareline studio设计好GUI&#xff0c;然后再导出其代码&#xff0c;在其…

实时数仓详解

前言 本文隶属于专栏《大数据理论体系》&#xff0c;该专栏为笔者原创&#xff0c;引用请注明来源&#xff0c;不足和错误之处请在评论区帮忙指出&#xff0c;谢谢&#xff01; 本专栏目录结构和参考文献请见大数据理论体系 背景 伴随着社会的发展&#xff0c;用户对数据仓库…