红茶的个人站点

  • 首页
  • 专栏
  • 开发工具
  • 其它
  • 隐私政策
Awalon
Talk is cheap,show me the code.
  1. 首页
  2. 专栏
  3. Spring Boot 学习笔记
  4. 正文

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

2023年7月3日 1186点热度 0人点赞 0条评论

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

本作品采用 知识共享署名 4.0 国际许可协议 进行许可
标签: entity spring 关联关系
最后更新:2023年7月3日

魔芋红茶

加一点PHP,加一点Go,加一点Python......

点赞
< 上一篇
下一篇 >

文章评论

取消回复

*

code

COPYRIGHT © 2021 icexmoon.cn. ALL RIGHTS RESERVED.
本网站由提供CDN加速/云存储服务

Theme Kratos Made By Seaton Jiang

宁ICP备2021001508号

宁公网安备64040202000141号