来自https://blog.csdn.net/china_shrimp/article/details/47357417,感谢作者无私分享。
继承是java的三大特性之一,这是众所周知的。在真实的开发环境中也运用的很多,比如说BaseDao,BaseAction。但是本文所要讨论的并不是这些,而是关于Entity的继承。就目前自己接触到的项目而言,Entity使用继承的比较少。但是在hibernate中,提供了关于Entity继承的内容,本文就简单的介绍一下。
Java代码侧,继承唯一的实现手段是使用关键字extends,而且不能多继承。在数据库一侧实现继承的话,实现继承的表结构有多种,Hibernate介绍了三种,分别是SINGLE_TABLE,TABLE_PER_CLASS,JOINED.这里介绍SINGLE_TABLE,JOINED。
现有三个类:Person(id,name),Student(id,name,score),Teacher(id,name,title)
在Java侧,Student和Teacher都从Person继承。
数据库侧
1.SINGLE_TABLE(单一表)用一张表来描述着三个Entity,那么就需要使用一个Flag Column 来区分该条记录是People,Student,Teacher。建好的表结构如下P_S_T(id,name,score,title,flg)。
flag=0,Person类,score和title字段都没有数据;
flag=1,Student类,score字段有数据,title字段没数据;
flag=2,Teacher类,score字段没数据,title字段有数据。
SINGLE_TABLE 方式Annotation实现
Person Entity
package com.bjsxt.hibernate;
import javax.persistence.DiscriminatorColumn;
import javax.persistence.DiscriminatorType;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
/**
*@Inheritance指定继承策略
*@DiscriminatorColumn 标志字段定义
*@DiscriminatorValue ,当数据为Person类时候,flg=0
*/
@Entity
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="flg", discriminatorType=DiscriminatorType.STRING)
@DiscriminatorValue("0")
public class Person {
private int id;
private String name;
@Id
@GeneratedValue
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Student Entity
package com.bjsxt.hibernate;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
/**
**@DiscriminatorValue ,当数据为Student类时候,flg=1
*/
@Entity
@DiscriminatorValue("1")
public class Student extends Person {
private int score;
public int getScore() {
return score;
}
public void setScore(int score) {
this.score = score;
}
}
Teacher Entity
package com.bjsxt.hibernate;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
/**
**@DiscriminatorValue ,当数据为Teacher类时候,flg=2
*/
@Entity
@DiscriminatorValue("2")
public class Teacher extends Person {
private String title;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
}
- JOINED 使用外键连接的方式实现继承
三张表分别如下
Person(id,name);
Student(id,score),id 参照Person的id
Teacher(id,title),id 参照Person的id。
JOINED 方式Annotation实现
Person Entity
package com.bjsxt.hibernate;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
@Entity
@Inheritance(strategy=InheritanceType.JOINED)
public class Person {
private int id;
private String name;
@Id
@GeneratedValue
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Student Entity
package com.bjsxt.hibernate;
import javax.persistence.Entity;
@Entity
public class Student extends Person {
private int score;
public int getScore() {
return score;
} //Person p = Person(load(1));
public void setScore(int score) {
this.score = score;
}
}
Teacher Entity
package com.bjsxt.hibernate;
import javax.persistence.Entity;
@Entity
public class Teacher extends Person {
private String title;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
}
以上是SINGLE_TABLE和JOINED的使用。
二者的比较:SINGLE_TABLE 只有一张表很方便,但是可能会造成大量的数据冗余,很多字段都是空的。JOINED方式虽然表多,但是逻辑是很清楚的。关于二者的使用,具体情况具体分析。