JPA中entity的一些功能

时间:2022-09-11 12:41:25

JPA中一个最基本的概念应该算是entity了,一般中文称为实体,有了解过UML、E-R图、软件工程的应该了解这个entity的概念。JPA中entity提供的各种接口,其基本的理念应该也是为了能实现像E-R图中类似的功能。

JPA中的entity最后是作为可以存储的单元,一个entity一方面类似于数据库中的一个table;另一方面entity也是一个java对象,对象间又存在一定的关系。一个最简单的例子是,比如我们数据库中的所有表都有一个id作为记录的唯一标示,因此希望通过继承的方式来做好比下图:

JPA中entity的一些功能

这里可以使用JPA中的@MappedSuperclass去标记父类,而子类加@Entity,这样父类不会作为Persistent(存储单元),而子类则可以,好比下面情况:

@MappedSuperclass
public class CommonColumn {
    @Id
    @GeneratedValue
    private Integer id;
    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }   
}

 

@Entity

public class Person extends CommonColumn{  
    private String lastName;
    private String firstName;


    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }   
}

这是一种entity的一种功能。

另外entity还可以有三种的继承策略(Entity Inheritance Mapping Strategies):

public enum InheritanceType {
    SINGLE_TABLE,
    JOINED,
    TABLE_PER_CLASS
};
默认情况下继承使用第一种策略SINGLE_TABLE,如果想更改可以在父类中添加@Inheritence来改变策略,这里说下第一种情况就是SINGLE_TABLE的情况
SINGLE_TABLE表示所有父类的子类都映射到数据库的同一张表里,好比下面图所示:

上面黄色的是类的结果,下面蓝色的是数据库表的结果,这样上面的两个类就映射到下面的一张表,为了区别是表中的记录是属于哪个类的,需要一个列来进行
区别这个就是所谓的@DiscriminatorColumn,这里是DTYPE也是默认的情况,默认的数据类型是String,需要更改可以在父类定义前加入
@DiscriminatorColumn(discriminatorType=DiscriminatorType.INTEGER)。最后在返回数据时JPA根据DTYPE会将数据转化为对应的类。

比如下面是个球类的java代码,同上面类似:
//这个是父类
@Entity
@DiscriminatorColumn(discriminatorType=DiscriminatorType.INTEGER)
public abstract class Ball {
@Id
@GeneratedValue
private Integer id;
private int shape;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public int getShape() {
return shape;
}
public void setShape(int shape) {
this.shape = shape;
}

}
//下面的是子类,定义了DTYPE为2的时候表示的是篮球 1的时候为足球
@Entity
@DiscriminatorValue(value="2")
public class BasketBall extends Ball {
private String basketBall;
public String getBasketBall() {
return basketBall;
}

public void setBasketBall(String basketBall) {
this.basketBall = basketBall;
}

}
@Entity
@DiscriminatorValue(value="1")
public class FootBall extends Ball {

private int footBall;

public int getFootBall() {

return footBall;
}

public void setFootBall(int footBall) {
this.footBall = footBall;
}
}
数据库创建就是create table Ball(
id integer not null auto_increment,
shape integer not null ,
footBall integer ,
basketBall varchar(40),
DTYPE integer not null,
primary key (id)
)
上面所说的是SINGLE_TABLE式的策略,TABLE_PER_CLASS则是每个类对应一个表,将会如下图:


 最后一个就是JOINED则情况如下图,分为三个表,每个表有独立的主键,子表不继承父表中的字段,子表通过外键同父表关联,从而获得相应的属性,
当然在sql中可以通过jion来获得完整的记录。

参考:http://download.oracle.com/javaee/5/tutorial/doc/bnbqa.html