JPA学习记录三( @DiscriminatorColumn用法)

xiaoxiao2021-02-28  110

[java]  view plain  copy  print ? 1、多个entity对应同一张表,用一个字段区分   @Entity   @Cache(usage = CacheConcurrencyStrategy.READ_WRITE)   @Table(name = "GRP_UNITINFO")   @Inheritance(strategy = InheritanceType.SINGLE_TABLE)   @DiscriminatorColumn(name = "GROUPFLG", discriminatorType = DiscriminatorType.STRING)   @DiscriminatorOptions(force=true)   @DiscriminatorValue(value = "2")   public class Unitinfo extends BaseActiveEntity implements java.io.Serializable {   [java]  view plain  copy  print ? @Entity   @Table(name = "GRP_UNITINFO")   @Inheritance(strategy = InheritanceType.SINGLE_TABLE)   @DiscriminatorColumn(name = "GROUPFLG", discriminatorType = DiscriminatorType.STRING)   @DiscriminatorOptions(force=true)   @DiscriminatorValue(value = "1")   public class Subgroup extends BaseActiveEntity implements java.io.Serializable{   [java]  view plain  copy  print ? @Entity   @Cache(usage=CacheConcurrencyStrategy.READ_WRITE)   @Table(name = "GRP_UNITINFO")   @Inheritance(strategy = InheritanceType.SINGLE_TABLE)   @DiscriminatorColumn(name = "GROUPFLG", discriminatorType = DiscriminatorType.STRING)   @DiscriminatorOptions(force=true)   @DiscriminatorValue(value = "0")   [java]  view plain  copy  print ? @DiscriminatorOptions(force=true)可以用@ForceDiscriminator(org.hibernate.annotations.<em>ForceDiscriminator</em>)代替      @DiscriminatorColumn@DiscriminatorOptions(force=true)在使用时,大部分情况下应该一起使用才不会出问题,但为什么Hibernate却必须在使用时要指定@DiscriminatorOptions,而且@DiscriminatorOptions中force的默认值还是false呢?   当使用Discriminator应用于单表时,才需要使用@DiscriminatorOptions(force=true),应用于JOIN_TABLE时,不需要此注解      原文详见:http://stackoverflow.com/questions/12199874/about-the-use-of-forcediscriminator-discriminatoroptionsforce-true      首先看一下最顶层的父类EmployeeEO,代码如下所示。            EmployeeEO      @Entity      @Table(name = "tb_employee")      /**继承映射策略*/      @Inheritance(strategy=InheritanceType.SINGLE_TABLE)      /**标识字段定义*/      @DiscriminatorColumn(      name="employee_type",discriminatorType=DiscriminatorType.STRING      )      /**该类的标识*/      @DiscriminatorValue("employee")      public class EmployeeEO implements Serializable {                             private Integer id;               private String name;                             @Id               @GeneratedValue(strategy = GenerationType.AUTO)               public Integer getId() {                         return id;               }               public void setId(Integer id) {                         this.id = id;               }               public String getName() {                         return name;               }               public void setName(String name) {                         this.name = name;               }      }      在最顶层的父类中,通常要做以下映射:      l         使用@Entity注释,标识该类以及所有的子类都映射到指定的表中,如果不标注,也可使用默认值。      l         使用@Inheritance注释,标识该类的子类继承映射的方式,该注释的定义如一下所示:      @Target({TYPE}) @Retention(RUNTIME)      public @interface Inheritance {      InheritanceType strategy() default SINGLE_TABLE;      }      其中,InheritanceType有三种类型,即7.4.2小节中讲述的三种类型,三种类型定义为常量,默认为SINGLE_TABLE。      public enum InheritanceType      { SINGLE_TABLE, JOINED, TABLE_PER_CLASS };      SINGLE_TABLE表示继承关系的实体保存在一个表;JOINED表示每个实体子类保存在一个表;TABLE_PER_CLASS表示每个实体类保存在一个表。这里使用的是第一种策略,所以定义的代码如下所示:      @Inheritance(strategy=InheritanceType.SINGLE_TABLE)      l         使用@DiscriminatorColumn注释,标识改继承层次上所区别每个实体的类型字段。它的定义如以下所示:      @Target({TYPE}) @Retention(RUNTIME)      public @interface DiscriminatorColumn {      String name() default "DTYPE";      DiscriminatorType discriminatorType() default STRING;      String columnDefinition() default "";      int length() default 31;      }      其中,@DiscriminatorColumn在使用时要注意以下这些问题。      1@DiscriminatorColumn只能标注在顶层的类中,而不能标注在子类中。      2@DiscriminatorColumn只在继承策略为“SINGLE_TABLE”和“JOINED”时使用。      3)name属性表示所标识具体类型的字段名称,默认为“DTYPE”,例如本例中使用的是字段“employee_type”,所以定义如下。      @DiscriminatorColumn(name="employee_type")      4)discriminatorType属性表示标识值的类型,默认为STRING字符串。它使用的枚举类型如下所示。      public enum DiscriminatorType { STRING, CHAR, INTEGER };      也就是说,标识值可以为String、Char或者Integer      5)columnDefinition属性表示生成字段的DDL语句,与@Column中的columnDefinition属性类似。      6)length属性表示为标识值的长度,默认为31。该属性只在使用DiscriminatorType. STRING时才需要设置。      l         使用@DiscriminatorValue注释,标注该实体类所实体标识字段的值,它的定义如下:      @Target({TYPE}) @Retention(RUNTIME)      public @interface DiscriminatorValue {      String value();      }      value的值表示所该实体的标注值。例如,标识字段“employee_type”的值为“employee”时可以认为是EmployeeEO实体。代码设置如下所示:      @DiscriminatorValue("employee")         <pre name="code" class="plain"2、在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(子类实体辨别字段列值)      在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

转载:http://blog.csdn.net/jiana227/article/details/46429235

转载请注明原文地址: https://www.6miu.com/read-62390.html

最新回复(0)