JPA继承方式
在JPA中,实体继承关系的映射策略共有三种:单表继承策略(SINGLE_TABLE)、Joined策略和Table_PER_Class策略。
关联注解
@Inheritance
用来配置父类
InheritanceType.SINGLE_TABLE
单表模式:将所有实现类的所有字段映射到一个表里。InheritanceType.TABLE_PER_CLASS
独立表模式: 将每个实现类合并基类的字段映射到单独的表里,每个表相关独立且没有关联。InheritanceType.JOINED
关联表模式:将基类和每个实现类分别映射到独立的表里,并使用主键进行关联,实现类只包含自己独有的字段。
-
@DiscriminatorColumn(name = "member_type")
用来做实现类区别标识的字段,如果不指定name,则会自动新建dtype字段。此字段系统会自动赋值,不需要人为指定。 -
@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;
}