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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章