在JPA中可以通过@Inheritance和@DiscriminatorColumn注解实现多态关系映射。
@Inheritance注解:
- 用于标注实体类的继承结构,指定其映射策略。
- 继承结构的根实体需要标注该注解。
@DiscriminatorColumn注解:
- 用于指定鉴别器列,存储实体类型信息,方便实体类型的区分与查询。
JPA支持3种继承映射策略:
- JOINED:每个子类拥有自己的表,并且有外键连接父表。
- TABLE_PER_CLASS:每个子类拥有自己的表,没有连接关系。
- SINGLE_TABLE:所有子类共用一张表,通过鉴别器列区分类型。
示例:
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "type")
public abstract class Person { ... }
@Entity
public class Employee extends Person { ... }
@Entity
public class Customer extends Person { ... }
上例定义了Person作为根实体,Employee和Customer作为其子类实体,使用SINGLE_TABLE策略映射到同一张表,type鉴别器列区分实体类型。
这个例子的优点是:
- 简单方便,所有子类共用一张表,通过discriminator值区分类型。
- 避免表连接,提高读取性能。
缺点是表结构相对复杂,需要discriminator列及各类型专有的字段。
多态关系的查询:
- 可以通过型别字段查询子类型实体,或者通过实体类型查询其派生实体。
- 需要使用TREAT或CAST函数进行类型转换。
示例:
// 查询Employee类型
Query query = em.createQuery("SELECT p FROM Person p WHERE p.type = 'Employee'");
// 也可以
Query query = em.createQuery("SELECT p FROM Employee p");
// 向下转型
Person p = em.find(Person.class, 1);
Employee e = (Employee) p;