在JPA中,实体继承关系的映射策略共有三种:单表继承策略(SINGLE_TABLE)、Joined策略和Table_PER_Class策略。
1、单表继承策略
单表继承策略,父类实体和子类实体共用一张数据库表,在表中通过一列辨别字段来区别不同类别的实体。具体做法如下:
a.在父类实体的@Entity注解下添加如下的注解:
@Inheritance(Strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name=”辨别字段列名”)
@DiscriminatorValue(父类实体辨别字段列值)
b.在子类实体的@Entity注解下添加如下的注解:
@DiscriminatorValue(子类实体辨别字段列值)
定义了一个父类
1 @Entity
2 @Inheritance(strategy = InheritanceType.SINGLE_TABLE)
3 @Table(name = "WINDOW_FILE")
4 @DiscriminatorColumn(name = "DISCRIMINATOR", discriminatorType = DiscriminatorType.STRING, length = 30)
5 @DiscriminatorValue("WindowFile")
6 public class WindowFile {
7
8 @Id
9 @GeneratedValue(strategy = GenerationType.AUTO)
10 private Integer id;
11
12 @Basic
13 @Column(name = "NAME")
14 private String name;
15
16 @Basic
17 @Column(name = "TYPE")
18 private String type;
19
20 @Basic
21 @Column(name = "DATE")
22 private Date date;
23 //省略get set
24 }
后定义2个子类
1 @Entity
2 @DiscriminatorValue("Folder")
3 public class Folder extends WindowFile {
4
5 @Basic
6 @Column(name = "FILE_COUNT")
7 private Integer fileCount;
8 //省略get set
9 }
1 @Entity
2 @DiscriminatorValue("Document")
3 public class Document extends WindowFile {
4
5 @Basic
6 @Column(name = "SIZE")
7 private String size;
8 //省略get set
9 }
以上通过列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类似。
如果使用xml配置文件则配置如下:
<hibernate-mapping>
<class name="com.baobaotao.domain.WindowFile" table="WINDOW_FILE"
catalog="sampledb" discriminator-value="WindowFile">
<id name="id" type="java.lang.Integer">
<column name="id" />
<generator class="identity" />
</id>
<!-- 加入鉴别标签,且必须放在id后面 -->
<discriminator column="DISCRIMINATOR" type="string">
</discriminator>
<property name="name" type="java.lang.String">
<column name="NAME" length="50" not-null="true" />
</property>
<property name="date" type="java.util.Date">
<column name="DATE" not-null="true">
</column>
</property>
<subclass name="com.baobaotao.domain.MainPost"
discriminator-value="Folder">
<property name="fileCount">
<column name="FILE_COUNT"></column>
</property>
</subclass>
<subclass name="com.baobaotao.domain.MainPost"
discriminator-value="Document">
<property name="size">
<column name="SIZE"></column>
</property>
</subclass>
</class>
</hibernate-mapping>
2、Joined策略
父类实体和子类实体分别对应数据库中不同的表,子类实体的表中只存在其扩展的特殊属性,父类的公共属性保存在父类实体映射表中。具体做法:
@Inheritance(Strategy=InheritanceType.JOINED)
子类实体不需要特殊说明。
父类代码:
1 @Entity
2 @Table(name = "T_ANIMAL")
3 @Inheritance(strategy = InheritanceType.JOINED)
4 public class Animal {
5
6 @Id
7 @Column(name = "ID")
8 @GeneratedValue(strategy = GenerationType.AUTO)
9 private Integer id;
10
11 @Column(name = "NAME")
12 private String name;
13
14 @Column(name = "COLOR")
15 private String color;
16 //省略get set
17 }
子类代码:
1 @Entity
2 @Table(name = "T_BIRD")
3 @PrimaryKeyJoinColumn(name = "BIRD_ID")
4 public class Bird extends Animal {
5
6 @Column(name = "SPEED")
7 private String speed;
8 //省略get set
9 }
1 @Entity
2 @Table(name = "T_DOG")
3 @PrimaryKeyJoinColumn(name = "DOG_ID")
4 public class Dog extends Animal {
5
6 @Column(name = "LEGS")
7 private Integer legs;
8 //省略get set
9 }
实际表结构如下:
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)
父类代码:
1 @Entity
2 @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
3 @Table(name = "T_VEHICLE")
4 public class Vehicle { // 基类
5
6 @Id
7 // @GeneratedValue
8 @Column(name = "ID")
9 private Integer id;
10
11 @Column(name = "SPEED")
12 private Integer speed;// 速度
13 //省略get set
14 }
子类代码:
1 @Entity
2 @Table(name = "T_CAR")
3 public class Car extends Vehicle {
4
5 @Column(name = "ENGINE")
6 private String engine;// 发动机
7 //省略get set
8 }
一旦使用这种策略就意味着你不能使用AUTO generator 和IDENTITY generator,即主键值不能采用数据库自动生成。
实际表结构如下:
T_VEHICLE ID,SPEED
T_CAR ID,SPEED,ENGINE