JPA 继承方式

本文详细介绍了在数据库设计中如何运用单表继承、Joined和Table_PER_Class三种策略来实现子类和父类实体的继承关系。通过实例展示了如何在Java实体类中应用这些策略,并解释了它们在实际数据库表结构中的体现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.单表继承策略

单表继承策略,父类实体和子类实体共用一张数据库表,在表中通过一列辨别字段来区别不同类别的实体。具体做法如下:

a.在父类实体的@Entity注解下添加如下的注解:

@Inheritance(Strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name=”辨别字段列名”)
@DiscriminatorValue(父类实体辨别字段列值)

b.在子类实体的@Entity注解下添加如下的注解:

@DiscriminatorValue(子类实体辨别字段列值) 

定义了一个父类

@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@Table(name = "WINDOW_FILE")
@DiscriminatorColumn(name = "DISCRIMINATOR", discriminatorType = DiscriminatorType.STRING, length = 30)
@DiscriminatorValue("WindowFile")
public class WindowFile {

	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	private Integer id;

	@Basic
	@Column(name = "NAME")
	private String name;

	@Basic
	@Column(name = "TYPE")
	private String type;

	@Basic
	@Column(name = "DATE")
	private Date date;
	//省略get set
}

后定义2个子类

@Entity
@DiscriminatorValue("Folder")
public class Folder extends WindowFile {

	@Basic
	@Column(name = "FILE_COUNT")
	private Integer fileCount;
	//省略get set
}


@Entity
@DiscriminatorValue("Document")
public class Document extends WindowFile {

	@Basic
	@Column(name = "SIZE")
	private String size;
	//省略get set
}

以上通过列DISCRIMINATOR的不同,区分具体父子实体。


实际表结构如下:

WINDOW_FILE  DISCRIMINATOR,ID,NAME,DATE,TYPE,SIZE,FILE_COUNT

当你使用WindowFile实体时,实际表的字段为DISCRIMINATOR='WindowFile',SIZE与FILE_COUNT永远是空

当使用Folder实体时,DISCRIMINATOR='Folder',SIZE永远是空,FILE_COUNT为实际值。

Document同理,与Folder类似。

2.Joined策略

 父类实体和子类实体分别对应数据库中不同的表,子类实体的表中只存在其扩展的特殊属性,父类的公共属性保存在父类实体映射表中。具体做法:

@Inheritance(Strategy=InheritanceType.JOINED)


子类实体不需要特殊说明。

@Entity
@Table(name = "T_ANIMAL")
@Inheritance(strategy = InheritanceType.JOINED)
public class Animal {

	@Id
	@Column(name = "ID")
	@GeneratedValue(strategy = GenerationType.AUTO)
	private Integer id;

	@Column(name = "NAME")
	private String name;

	@Column(name = "COLOR")
	private String color;
	//省略get set
}
@Entity
@Table(name = "T_BIRD")
@PrimaryKeyJoinColumn(name = "BIRD_ID")
public class Bird extends Animal {

	@Column(name = "SPEED")
	private String speed;
	//省略get set
}
@Entity
@Table(name = "T_DOG")
@PrimaryKeyJoinColumn(name = "DOG_ID")
public class Dog extends Animal {

	@Column(name = "LEGS")
	private Integer legs;
	//省略get set
}

实际表结构如下:

T_ANIMAL  ID,COLOR,NAME

T_BIRD  SPEED,BIRD(既是外键,也是主键)

T_DOG  LEGS,DOG_ID(既是外键,也是主键)

3.Table_PER_Class策略:


Table_PER_Class策略,父类实体和子类实体每个类分别对应一张数据库中的表,子类表中保存所有属性,包括从父类实体中继承的属性。具体做法:

只需在父类实体的@Entity注解下添加如下注解:

@Inheritance(Strategy=InheritanceType.TABLE_PER_CLASS)

@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
@Table(name = "T_VEHICLE")
public class Vehicle { // 基类

	@Id
	// @GeneratedValue
	@Column(name = "ID")
	private Integer id;

	@Column(name = "SPEED")
	private Integer speed;// 速度
	//省略get set
}
@Entity
@Table(name = "T_CAR")
public class Car extends Vehicle {

	@Column(name = "ENGINE")
	private String engine;// 发动机
	//省略get set
}

一旦使用这种策略就意味着你不能使用AUTO generator 和IDENTITY generator,即主键值不能采用数据库自动生成。


实际表结构如下:

T_VEHICLE  ID,SPEED

T_CAR  ID,SPEED,ENGINE



转载于:https://my.oschina.net/liyonglee/blog/374817

### JPA 中 `JpaSpecificationExecutor` 与 `JpaRepository` 的区别 #### 功能对比 `JpaRepository` 提供了一组标准的 CRUD 方法以及分页和排序功能,适用于大多数基本的数据访问需求。通过继承 `JpaRepository<T, ID>` 接口,开发者可以立即获得诸如保存、删除、查找等常用操作的支持[^4]。 而 `JpaSpecificationExecutor` 则专注于动态查询构建的功能。它允许使用 Specifications 来创建复杂的条件组合,从而实现更灵活多变的查询逻辑。Specifications 可以看作是一种可重用的查询片段定义方式,能够方便地拼接多个查询条件来满足不同的业务需求。 ```java public interface IBigDao extends JpaRepository<BigEntity, Long>, JpaSpecificationExecutor<BigEntity> { BigEntity findByAlarmContentAndAlarmState(String alarmContent, EAlarmState alarmState); } ``` 此代码展示了如何在一个自定义仓库接口中同时集成这两种能力,既保留了基础的操作又增强了高级查询的能力。 #### 使用场景 对于简单的数据存取任务或者固定模式下的检索请求来说,仅依赖于 `JpaRepository` 就已经足够强大并易于维护;然而当面对复杂且变化频繁的查询要求时,则推荐引入 `JpaSpecificationExecutor` 。这不仅有助于提高代码复用率,还能让应用程序更好地适应未来可能发生的改动或扩展。 #### 继承关系说明 值得注意的是,在 Spring Data JPA 的设计体系里,`QueryByExampleExecutor` 被视为 `JpaRepository` 的父级接口之一,意味着所有实现了前者特性的库也会自动拥有后者的一部分行为特性[^3]。不过这里提到的关系并不直接影响到 `JpaSpecificationExecutor` 和 `JpaRepository` 之间的差异比较。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值