您的位置:首页 > 文旅 > 美景 > 中国软装设计师的薪资水平_我图网_企业线上培训课程_seo优化方法网站快速排名推广渠道

中国软装设计师的薪资水平_我图网_企业线上培训课程_seo优化方法网站快速排名推广渠道

2024/12/23 9:10:01 来源:https://blog.csdn.net/qq_35215728/article/details/143572175  浏览:    关键词:中国软装设计师的薪资水平_我图网_企业线上培训课程_seo优化方法网站快速排名推广渠道
中国软装设计师的薪资水平_我图网_企业线上培训课程_seo优化方法网站快速排名推广渠道

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

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

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

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

实体如下

@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;
}
@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 中加入

@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 中加入

@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"])
      

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

      @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 方法设置值。这通常用于只写属性(可选)


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

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com