Spring Data Jpa - 实体继承

JPA继承方式

在JPA中,实体继承关系的映射策略共有三种:单表继承策略(SINGLE_TABLE)、Joined策略和Table_PER_Class策略。

关联注解

  1. @Inheritance用来配置父类
  • InheritanceType.SINGLE_TABLE 单表模式:将所有实现类的所有字段映射到一个表里。
  • InheritanceType.TABLE_PER_CLASS独立表模式: 将每个实现类合并基类的字段映射到单独的表里,每个表相关独立且没有关联。
  • InheritanceType.JOINED 关联表模式:将基类和每个实现类分别映射到独立的表里,并使用主键进行关联,实现类只包含自己独有的字段。
  1. @DiscriminatorColumn(name = "member_type") 用来做实现类区别标识的字段,如果不指定name,则会自动新建dtype字段。此字段系统会自动赋值,不需要人为指定。

  2. @DiscriminatorValue("wexin") 实现类区别的标识值,jpa会根据具体标识值将数据持久化到对应的表中,查询语句也可自动识别类型

操作

  • 所有的实现类都可视为一个整体,可直接使用某个子类的属性做查询条件,可以有子类的返回值,也可以设置基类返回值。
  • 如果返回值为基类Member,jpa则返回Hibernate的代理类,需要Hibernate.unproxy(member)才能得到具体的实现类
  • 如果返回值为实现类则可以直接使用
  • 写入和删除操作,jpa都视为一个整体,可以直接使用memberRepository默认的方法

关联表模式如何保留审计字段或同名字段

Jpa在关联表模式下,对子类中与父类同名的字段不进行管理,导致自定义的软删除字段不会生效,也不生成对应的表字段,解决这个问题,可以创建一个不同名属性,映射到指定的字段,实现功能。

/**
 * 计量容器基础表
 * @author xxm
 * @date 2020/7/22
 */
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@Table(name = "mms_bd_container_base")
@DiscriminatorColumn(name = "containerType")
@SQLDelete(sql = "update mms_bd_container_base set deleted=" + AppConst.FLAG_DELETED + " where id=?")
@Where(clause = "deleted=" + AppConst.FLAG_NOT_DELETED)
public class ContainerDo extends BaseEntity{
    /** 编号 */
    @Column(unique = true)
    private String no;
    /** 容器类型 */
    @Column(insertable = false,updatable = false)
    private String containerType;
    /** 容器状态 */
    private String containerStatus;
    /** 识别码 */
    private String identifier;
    /** 识别码类型 */
    private String identifierType;
}
/**
 * 容器(车辆)
 * @author xxm
 * @date 2020/7/22
 */
@Entity
@Table(name = "mms_bd_container_vehicle")
@DiscriminatorValue("vehicle")
@SQLDelete(sql = "update mms_bd_container_vehicle set deleted=" + AppConst.FLAG_DELETED + " where id=?")
@Where(clause = "deleted=" + AppConst.FLAG_NOT_DELETED)
public class ContainerVehicleDo extends ContainerDo implements EntityBaseFunction<containervehicledto> {
    /** 车辆名称 */
    private String vehicleName;
    /** 重量 */
    private Double weight;
    /** 计量时间 */
    private LocalDateTime weighingTime;
    /** 重量有效期类型 */
    private String validPeriod;
    /** 删除标志(父类同名属性) */
    @Column(name = "deleted")
    private boolean deleted0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章