您的位置:首页 > 其它

Hibernate之jpa实体映射的三种继承关系

2017-03-21 17:07 597 查看
在JPA中,实体继承关系的映射策略共有三种:单表继承策略(table per class)、Joined策略(table per subclass)和Table_PER_Class策略。
 
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

分类: hibernate
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: