JPA继承方式

Posted ゞ清茶℡

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JPA继承方式相关的知识,希望对你有一定的参考价值。

  在JPA中,实体继承关系的映射策略有三种:

一:SINGLE_TABLE策略 

二:JOINED策略 

三:TABLE_PER_CLASS策略

在JPA中,默认的是使用第一种继承策略,即单表继承策略。


1.单表继承策略 SINGLE_TABLE

父类实体和子类实体共用一张数据库表,在表中通过一个辨别字段的值来区分不同类别的实体。

在父类中Entity的定义如下:

@Entity
@Table(name = "父表的名称")
@Inheritance(Strategy=InheritanceType.SINGLE_TABLE) //单表继承策略
@DiscriminatorColumn(name=”辨别字段列名”)
@DiscriminatorValue(父类实体辨别字段列值)

在子类中Entity的定义如下:

@Entity
@Table(name = "子表的名称")
@DiscriminatorValue("子类实体辨别字段列值")

举例如下:

 1 @Entity  
 2 @Inheritance(strategy = InheritanceType.SINGLE_TABLE)  
 3 @Table(name = "WINDOW_FILE")  
 4 @DiscriminatorColumn(name = "DISCRIMINATOR", discriminatorType = DiscriminatorType.STRING, length = 30)  // 指定辨别字段的类型为String,长度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 }

 子类Folder定义

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 }  

子类Document定义

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 }  

通过在父类中指定继承方式为@Inheritance(strategy = InheritanceType.SINGLE_TABLE),再指定辨别字段,通过辨别字段的值来区分父子实体。

生成的表结构如下:

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

当你使用WindowFile实体时,实际表的字段为 DISCRIMINATOR=‘WindowFile‘, 字段:SIZE 和 FILE_COUNT永远是空。

当使用Folder实体时,DISCRIMINATOR=‘Folder‘,字段:SIZE永远是空,字段:FILE_COUNT为实际set的值。

当使用Document实体时,DISCRIMINATOR=‘Document‘,字段:FILE_COUNT永远是空,字段:SIZE为实际set的值。


2.JOINED策略

  父类实体和子类实体分别对应数据库中不同的表,父类定义的内容为子类们公共的属性,子类实体中定义的内容为扩展的属性。

在父类中Entity的定义如下:

@Entity
@Table(name = "父表的名称")
@Inheritance(Strategy=InheritanceType.JOINED) // JOINED继承策略
@DiscriminatorColumn(name=”辨别字段列名”)

在子类中Entity的定义如下:

@Entity
@Table(name = "子表的名称")
@DiscriminatorValue("子类实体辨别字段列值")

举例如下:

父类定义如下:

 1 @Entity  
 2 @Table(name = "T_ANIMAL")  
 3 @Inheritance(strategy = InheritanceType.JOINED)  
 4 @DiscriminatorColumn(name = "AAA")  // 辨别字段 AAA
 5 public class Animal {  
 6   
 7     @Id  
 8     @Column(name = "ID")  
 9     @GeneratedValue(strategy = GenerationType.AUTO)  
10     private Integer id;  
11   
12     @Column(name = "NAME")  
13     private String name;  
14   
15     @Column(name = "COLOR")  
16     private String color;  
17     //省略get set  
18 }  

子类1Bird定义如下

@Entity  
@Table(name = "T_BIRD") 
@DiscriminatorValue("Bird")
public class Bird extends Animal { @Column(name = "SPEED") private String speed; //省略get set }

子类2Dog定义如下

@Entity  
@Table(name = "T_DOG")  
@DiscriminatorValue("Dog")
public class Dog extends Animal {  
  
    @Column(name = "LEGS")  
    private Integer legs;  
    //省略get set  
}  

实际生成的表结构如下:

表:T_ANIMAL,字段:  ID,COLOR,NAME

表:T_BIRD  ,字段: SPEED,ID(既是外键,也是主键)

表:T_DOG,字段:   LEGS,ID(既是外键,也是主键)


3.TABLE_PER_CLASS策略

父类实体和子类实体各自生成表,实体对应自己生成的表,子类实体对应的表的字段保存所有的属性,包括从父类实体中继承的属性。

在父类中Entity的定义如下:

@Entity
@Table(name = "父表的名称")
@Inheritance(Strategy=InheritanceType.TABLE_PER_CLASS) // TABLE_PER_CLASS继承策略

在子类中Entity的定义如下:

@Entity
@Table(name = "子表的名称")

举例如下:

父类定义如下:

@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

总结:在使用JPA开发的过程的中,基本用到的@Inheritance(Strategy=InheritanceType.SINGE_TABLE)和@Inheritance(Strategy=InheritanceType.JOINED)这两种继承策略比较多。第三种在实际开发中目前没有用到过。

参考资料:http://zhuchengzzcc.iteye.com/blog/1679496

 

 

以上是关于JPA继承方式的主要内容,如果未能解决你的问题,请参考以下文章

Java /JPA |具有指定继承类型的查询

深入Django ORM的继承关系

单表继承(休眠)的 JPA 2 标准查询

spring jpa dao是怎么自动实现的

JPA

SpringBoot + JPA问题汇总