spring-data-jpa 一对多,多对一,多对多

news/2024/11/7 19:08:00/

springdatajpa__0">spring-data-jpa 一对多,多对一,多对多

首先介绍几个主要用到的注解

  • @ManyToOne 多对一
  • @ManyToMany 多对多
  • @OneToMany 一对多
  • @JoinColumn 两表之间的关联
  • @JsonIgnoreProperties 忽略属性(避免Jason套娃)

比如我有两张表:customerbill,一个customer数据对应bill中多条数据,两表通过 customer.idbill.customer_id 关联

实体如下

java">@Entity
@Table(name = "bill")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Bill {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Long id;@Column(name = "customer_id")private Long customerId;@Column(name = "bill_no")private String billNo;@Column(name = "bill_amount")private float billAmount;@Column(name = "bill_date")private LocalDate billDate;
}
java">@Entity
@Table(name = "customer")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Customer {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Long id;@Column(name = "customer_name")private String customerName;@Column(name = "customer_age")private Integer customerAge;@Column(name = "customer_account")private String customerAccount;@Column(name = "customer_password")private String customerPassword;
}

为了使两张表关联起来,需要在实体中加入关联的逻辑

customer.java 中加入

java">@OneToMany( targetEntity = Bill.class, fetch = FetchType.EAGER, cascade = {CascadeType.ALL})
@JsonIgnoreProperties(value = {"customer"})
@JoinColumn(name = "customer_id",referencedColumnName = "id",insertable = false,updatable = false )
private List<Bill> bills;

Bill.java 中加入

java">@ManyToOne(targetEntity = Customer.class, fetch = FetchType.EAGER, cascade = {CascadeType.ALL})
@JsonIgnoreProperties(value = {"bills"})
@JoinColumn(name = "customer_id",referencedColumnName = "id",insertable = false,updatable = false )
private Customer customer;

下面说说如何配置使用

@ManyToOne,@ManyToMany,@OneToMany

意义就不解释了,通过注解名称就可以看懂,只说明属性

  • targetEntity

    类型:Class<?>

    指定关系的另一端实体的类型。比如上述代码中,customer实体类与bill实体关联,所以我在customer类的bills属性上的注解@OneToMany的targetEntity属性赋值Bill.class;这个属性是可选的,如果不指定,spring-data-jpa 将根据字段的类型来确定目标实体类,建议写上。

  • fetch

    类型:javax.persistence.FetchType

    指定加载策略:立即加载(FetchType.EAGER)和 延迟加载(FetchType.LAZY)

    • 立即加载:加载主实体时,其关联的实体或集合也会同时被加载。这种策略通过减少数据库查询次数来提高性能,因为它尝试在一个查询中获取所有关联实体的数据

    • 延迟加载:加载主实体时,其关联的实体或集合不会立即被加载,而是在第一次访问关联属性时才进行加载。这种策略可以减少不必要的数据库查询,因为只有在实际需要数据时才会进行加载

      使用延迟加载,我遇到了一个坑,这里顺便记录,有时一条a表数据对应几十万条b表数据,使用立即加载肯定是不合适的,故而用了延迟加载,使用延迟加载的时候,报错如下

       No serializer found for class org.hibernate.proxy.pojo.bytebuddy.ByteBuddyInterceptor and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) (through reference chain: java.util.ArrayList[0]->com.train.spr.entities.Bill["customer"]->com.train.spr.entities.Customer$HibernateProxy$g4FqEJel["hibernateLazyInitializer"])
      

      如果你也遇到同样的问题,用如下方式解决
      在实体类名上加一句代码,如下

      java">@JsonIgnoreProperties(value = {"hibernateLazyInitializer"})
      public class Bill {
      // 实现(略)
      }
      
  • cascade

    类型:javax.persistence.CascadeType[]

    级联操作,定义哪些持久化操作(如保存、更新、删除)应该被级联到关系的另一端实体。CascadeType是枚举类,可选值如下

    • CascadeType.ALL:表示所有的持久化操作都会级联到关系的另一端实体。这包括:PERSIST、MERGE、REMOVE、REFRESH 和 DETACH
    • CascadeType.PERSIST:当实体的对象被创建时,相关的实体也会被级联保存
    • CascadeType.MERGE:当实体被合并到当前持久化上下文时,相关的实体也会被级联合并
    • CascadeType.REMOVE:当实体被删除时,相关的实体也会被级联删除(删customer表中一条数据,jpa自动删除bill表中关联数据)
    • CascadeType.REFRESH:当实体被刷新时,相关的实体也会被级联刷新
    • CascadeType.DETACH:当实体被分离出持久化上下文时,相关的实体也会被级联分离

@JoinColumns 关联关系集合

若两张表之间通过多个字段相关联,比如A表和B表通过A.CREATE_DATE = B.CREATE_DATE AND A.ID = B.A_ID相关联,使用 @JoinColumns 包裹 @JoinColumn 集合

@JoinColumn 关联关系

定义两个实体之间以什么字段相关联;属性如下

  • name

    类型:string

    指定本表关联其他表的本表列名称

  • referencedColumnName

    类型:string

    指定本表关联其他表的其他表列名称(其他表的列名称也叫做外键)

  • unique

    类型:bool

    指定外键列是否具有唯一性约束(可选,默认false),拿我给的例子来说,一个customer可以对应多个bill,但是一个bill仅能对应一个customer,所以bill类中customer属性的@JoinColumn注解的属性改为true,表示customer中仅能有唯一一个实体与之对应

  • nullable

    类型:bool

    指定外键列是否可以为 NULL(可选,默认true),表示列可以为 NULL

  • insertable

    类型:bool

    指定外键列是否在插入操作时可被插入(可选,默认true)

  • updatable

    类型:bool

    指定外键列是否在更新操作时可被更新(可选,默认true)

  • columnDefinition

    类型:string

    指定外键列的 SQL 类型定义。这允许你自定义列的 SQL 类型和大小等详细信息(可选)

  • table

    类型:string

    指定外键列所在的表的名称。这在多表继承的场景中使用

  • foreignKey

    类型:String

    指定外键约束的名称。如果未指定,spring-data-jpa根据实体关系自动生成一个外键约束名称(可选)

@JsonIgnoreProperties JSON属性忽略

如果实体类的关联属性上不加此注解,那么你查出来的json数据结构绝对是“套娃”;属性如下

  • value

    类型:string[]

    指定忽略对方实体类中的某个属性转换为json,比如我上述例子中 customer.java 中有属性 bills,而bill.java中又有customer,所以他俩得互相忽略对方实体类中对自己引用的属性名,故而customer实体中忽略bill中的customer,bill实体中忽略customer中的bills。这么说有点抽象哈,不过你自己试一试就很轻松能明白了

  • ignoreUnknown

    类型:boolean

    ignoreUnknown 属性只适用于从 JSON 数据到 Java 对象的反序列化过程,当设置为 true 时,如果 JSON 中包含未在 Java 类中定义的属性,这些属性将被忽略。这有助于处理 JSON 数据中可能存在的额外字段,而不会抛出异常(可选)

  • allowGetters

    类型:boolean

    当设置为 true 时,即使属性没有 setter 方法,也可以通过 getter 方法访问。这通常用于只读属性(可选)

  • allowSetters

    类型:boolean

    当设置为 true 时,即使属性没有 getter 方法,也可以通过 setter 方法设置值。这通常用于只写属性(可选)


暂且写到这儿,后续有总结再补


http://www.ppmy.cn/news/1545145.html

相关文章

Apache POI(java操作Miscrosoft Office)

Apache POI 1.1 介绍 Apache POI 是一个处理Miscrosoft Office各种文件格式的开源项目。简单来说就是&#xff0c;我们可以使用 POI 在 Java 程序中对Miscrosoft Office各种文件进行读写操作。 一般情况下&#xff0c;POI 都是用于操作 Excel 文件。 Apache POI 的应用场景&a…

5分钟科普:AI网关是什么?应用场景是什么?有没有开源的选择?

AI网关的功能及其定义 AI网关位于企业应用与内外部大模型调用的交汇点&#xff0c;能够灵活地将请求转发给内部自建模型或外部大模型服务提供商&#xff0c;甚至海外的服务商。它管理着企业所有的AI出口流量&#xff0c;为企业内的不同团队提供了多方面的优势。 对于开发团队…

【第六章·循环控制结构】第五节:流程的转移控制

目录 goto 语句 break 语句 示例&#xff1a;使用 goto 和 break 实现读入正整数程序&#xff0c;遇负数终止 用 goto 语句编程实现 用 break 语句编程实现 break 语句与 goto 语句的区别 continue 语句 break 语句与 continue 语句的区别 示例&#xff1a;使用 conti…

香橙派Zero3部署Talebook电子书库结合内网穿透随时随地享受阅读乐趣

文章目录 前言1. 添加镜像源2. 安装Talebook3. 简单使用介绍4. 安装内网穿透工具5. 配置固定公网地址 前言 本文主要介绍如何在刷了CasaOS轻NAS系统的香橙派Orange Pi Zero3中&#xff0c;使用Docker本地部署Talebook电子书管理系统并结合cpolar内网穿透实现远程管理本地书籍与…

DS二叉树--赫夫曼树解码

题目描述 已知赫夫曼编码算法和程序&#xff0c;在此基础上进行赫夫曼解码 可以增加一个函数&#xff1a;int Decode(const string codestr, char txtstr[]);//输入编码串codestr&#xff0c;输出解码串txtstr 该方法如果解码成功则返回1&#xff0c;解码失败则返回-1&…

Browserslist 配置

Browserslist 是一个工具和规范&#xff0c;用于定义和共享支持的浏览器列表&#xff0c;以便在前端开发中管理不同工具的兼容性。这些工具可以包括 Babel、Autoprefixer、ESLint 等&#xff0c;它们都可以使用 Browserslist 提供的配置来确定应支持哪些浏览器及其版本。 主要…

【Springboot问题】创建springboot项目后没有Resources文件夹及application文件

问题描述&#xff1a; 在创建springboot项目之后&#xff0c;由于项目识别的问题&#xff0c;没有出现资源文件夹以及application文件。 解决方法&#xff1a; 但是此刻依旧没有application.yml文件&#xff0c;创建

服务器上删除超大文件夹的解决方案

1.示例主脚本 delete_all_folders.sh 它会遍历指定目录下的所有子目录&#xff0c;并调用 delete_files.sh 脚本删除每个子目录中的文件和空目录 #!/bin/bash# 检查是否指定了根目录路径 if [ -z "$1" ]; thenecho "Usage: $0 <root_directory>"ex…