天天看点

程序员的量化交易之路(15)--Cointrader之EntityBase类(3)1. 类代码2. @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)注解说明3. @MappedSuperClass注解

EntityBase是其他实体类的基类。在这里我们先将代码贴出。需要说明的是,有些实体类是需要映射到数据库的。需要JPA基础,或者Hibernate基础。

这个类就是包含一个Id,唯一标示、还有就是一个版本号。利于升级。

@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)

@MappedSuperclass

public abstract class EntityBase implements Serializable {

    /**

     * 

     */

    private static final long serialVersionUID = -7893439827939854533L;

    @Id

    @Column(columnDefinition = "BINARY(16)", length = 16, updatable = false, nullable = false)

    public UUID getId() {

        ensureId();

        return id;

    }

    @Version

    private Long version;

    public Long getVersion() {

        return version;

    public void setVersion(Long version) {

        this.version = version;

    @Override

    public boolean equals(Object o) {

        // generated by IDEA

        if (this == o)

            return true;

        if (!(o instanceof EntityBase))

            return false;

        EntityBase that = (EntityBase) o;

        return id.equals(that.id);

    public int hashCode() {

        return id.hashCode();

    // JPA

    protected EntityBase() {

    protected void setId(UUID id) {

        this.id = id;

    private void ensureId() {

        if (id == null)

            id = UUID.randomUUID();

    private UUID id;

}

    在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(子类实体辨别字段列值) 

定义了一个父类

程序员的量化交易之路(15)--Cointrader之EntityBase类(3)1. 类代码2. @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)注解说明3. @MappedSuperClass注解

@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;  

    @Column(name = "TYPE")  

    private String type;  

    @Column(name = "DATE")  

    private Date date;  

    //省略get set  

}  

后定义2个子类

程序员的量化交易之路(15)--Cointrader之EntityBase类(3)1. 类代码2. @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)注解说明3. @MappedSuperClass注解

@DiscriminatorValue("Folder")  

public class Folder extends WindowFile {  

    @Column(name = "FILE_COUNT")  

    private Integer fileCount;  

程序员的量化交易之路(15)--Cointrader之EntityBase类(3)1. 类代码2. @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)注解说明3. @MappedSuperClass注解

@DiscriminatorValue("Document")  

public class Document extends WindowFile {  

    @Column(name = "SIZE")  

    private String size;  

 以上通过列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)

子类实体不需要特殊说明。

程序员的量化交易之路(15)--Cointrader之EntityBase类(3)1. 类代码2. @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)注解说明3. @MappedSuperClass注解

@Table(name = "T_ANIMAL")  

@Inheritance(strategy = InheritanceType.JOINED)  

public class Animal {  

    @Column(name = "ID")  

    @Column(name = "COLOR")  

    private String color;  

程序员的量化交易之路(15)--Cointrader之EntityBase类(3)1. 类代码2. @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)注解说明3. @MappedSuperClass注解

@Table(name = "T_BIRD")  

@PrimaryKeyJoinColumn(name = "BIRD_ID")  

public class Bird extends Animal {  

    @Column(name = "SPEED")  

    private String speed;  

程序员的量化交易之路(15)--Cointrader之EntityBase类(3)1. 类代码2. @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)注解说明3. @MappedSuperClass注解

@Table(name = "T_DOG")  

@PrimaryKeyJoinColumn(name = "DOG_ID")  

public class Dog extends Animal {  

    @Column(name = "LEGS")  

    private Integer legs;  

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)

程序员的量化交易之路(15)--Cointrader之EntityBase类(3)1. 类代码2. @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)注解说明3. @MappedSuperClass注解

@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)  

@Table(name = "T_VEHICLE")  

public class Vehicle { // 基类  

    // @GeneratedValue  

    private Integer speed;// 速度  

程序员的量化交易之路(15)--Cointrader之EntityBase类(3)1. 类代码2. @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)注解说明3. @MappedSuperClass注解

@Table(name = "T_CAR")  

public class Car extends Vehicle {  

    @Column(name = "ENGINE")  

    private String engine;// 发动机  

一旦使用这种策略就意味着你不能使用AUTO generator 和IDENTITY generator,即主键值不能采用数据库自动生成。

T_VEHICLE  ID,SPEED

T_CAR  ID,SPEED,ENGINE

@MappedSuperclass注解是为了在继承中,防止基类生成表格。在基类加上该标注,而不是@Entity,就可以只生成子类表,而子类表又含有基类的那些属性(列)。

实体类baseEntity.java

package com.rock.cft.hibernate;

import java.util.Date;

import javax.persistence.GeneratedValue;

import javax.persistence.GenerationType;

import javax.persistence.Id;

import javax.persistence.MappedSuperclass;

public abstract class BaseEntity {

  private Integer id;// 数据库主键

 private Date creationTime;//创建时间

 private Date modificationTime;//修改时间

 @Id

 @GeneratedValue(strategy = GenerationType.AUTO)

 public Integer getId() {

  return id;

 }

 public void setId(Integer id) {

  this.id = id;

 public Date getCreationTime() {

  return creationTime;

 public void setCreationTime(Date creationTime) {

  this.creationTime = creationTime;

 public Date getModificationTime() {

  return modificationTime;

 public void setModificationTime(Date modificationTime) {

  this.modificationTime = modificationTime;

package com.rock.cft.test.model;

import java.io.Serializable;

import javax.persistence.Column;

import javax.persistence.Entity;

import javax.persistence.Table;

import com.rock.cft.hibernate.BaseEntity;

@Entity

@Table(name="test_no2")

public class Test_No1 extends BaseEntity implements Serializable {

 private String name;

 private int age;

 public String getName() {

  return name;

 public void setName(String name) {

  this.name = name;

 public int getAge() {

  return age;

 public void setAge(int age) {

  this.age = age;

public class Test_NO2 extends BaseEntity implements Serializable {

 private Date testBri;

 private String testAdr;

 public Date getTestBri() {

  return testBri;

 public void setTestBri(Date testBri) {

  this.testBri = testBri;

 public String getTestAdr() {

  return testAdr;

 public void setTestAdr(String testAdr) {

  this.testAdr = testAdr;

 关于定义那些列的等具体细节,这里就不再说明了。