Hibernate继承关系映射
Hibernate会有三种映射方式
下面将会根据这个例子来进行举例
根据建立的表的个数
1、每个具体的类建一张表(即子类建两张表)
- 关系数据模型不支持域模型中的继承关系和多态
- 每个子类对应的表中同时存在父类继承的属性和自己特有的属性
- 如果父类不是抽象类并且也需要被持久化,还需要为父类建立对应的表
配置文件配置:
该种方式是需要两张表,两个配置文件的,另一个子类的配置文件类似
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.hibernate.entity">
<class name="SalariedEmployee" table="salariedemployee">
<id name="id">
<generator class="increment"></generator>
</id>
<property name="name"></property>
<property name="salary"></property>
</class>
</hibernate-mapping>
注解配置
父类:
@MappedSuperclass
public class Employee {
@Id
@GeneratedValue(generator = "generator_employee")
@GenericGenerator(name = "generator_employee",strategy = "increment")
private int id;
private String name;
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;
}
}
子类:
package com.hibernate.entity;
import javax.persistence.Entity;
import javax.persistence.Table;
@Entity
@Table(name="houremployee")
public class HourEmployee extends Employee{
private Double rate;
public Double getRate() {
return rate;
}
public void setRate(Double rate) {
this.rate = rate;
}
}
2、父类建立一张表
- 关系数据模型支持继承关系和多态
- 在表中加入额外的字段区分子类的类型,表中包含父类和所有子类的属性对应的字段
- 支持多态查询,就是从数据库中检索父类对象时,同时包含所有子类的对象
只使用一张表
通过配置文件来实现映射需要用到两个
- discriminator 必须要紧跟id元素,column属性为字段名称
- subclass 指定子类的相关配置
①discriminator-value要指定该区分字段的内容
②注意,如果父类也是需要持久化的,那么也需要指定该属性值是什么?
多态查询:可以通过指定子类的不同类型从而获取到不同的子类对象,注意要根据记录用对应对象接收。
SalariedEmployee employee = session.get(SalariedEmployee.class, new Integer(1));
配置文件配置。也只需要一个配置文件
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.hibernate.entity2">
<class name="Employee" table="employee">
<id name="id">
<generator class="increment"></generator>
</id>
<!-- 紧跟id元素,指定区分的属性是哪一个 -->
<discriminator column="employee_type"></discriminator>
<property name="name"></property>
<!-- 子类的配置 -->
<subclass name="HourlyEmployee" discriminator-value="HE">
<property name="rate"></property>
</subclass>
<subclass name="SalariedEmployee" discriminator-value="SE">
<property name="salary"></property>
</subclass>
</class>
</hibernate-mapping>
注解配置:
父类:
@Entity
@Table(name = "employee")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "employee_type")
public class Employee {
@Id
@GeneratedValue(generator = "increment_generator")
@GenericGenerator(name = "increment_generator",strategy = "increment")
private int id;
private String name;
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;
}
}
子类
因为只有一张表,就是需要指定该类型对应的type类型是什么。
@Entity
@DiscriminatorValue(value = "HE")
public class HourEmployee extends Employee{
private Double rate;
public Double getRate() {
return rate;
}
public void setRate(Double rate) {
this.rate = rate;
}
@Override
public String toString() {
return "HourEmployee [rate=" + rate + ", getId()=" + getId() + ", getName()=" + getName() + "]";
}
}
@Entity
@DiscriminatorValue(value = "SE")
public class SalariedEmployee extends Employee{
private Double salary;
public Double getSalary() {
return salary;
}
public void setSalary(Double salary) {
this.salary = salary;
}
@Override
public String toString() {
return "SalariedEmployee [salary=" + salary + ", getId()=" + getId() + ", getName()=" + getName() + "]";
}
}
3、每个类建立一张表
要注意这种方式是基于数据库表中已经存在了主外键关系才可以,要现在数据库表中设计好了主外键关系,再在配置文件中指定
- 映射文件
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.hibernate.entity3">
<class name="Employee" table="employee1">
<id name="id">
<generator class="increment"></generator>
</id>
<property name="name"></property>
<joined-subclass name="HourEmployee" table="houremployee1">
<key column="EMPLOYEEID"></key>
<property name="rate"></property>
</joined-subclass>
<joined-subclass name="SalariedEmployee" table="salariedemployee1">
<key column="EMPLOYEEID"></key>
<property name="salary"></property>
</joined-subclass>
</class>
</hibernate-mapping>
- 注解配置
父类
@Entity
@Table(name = "employee1")
@Inheritance(strategy = InheritanceType.JOINED)
public class Employee {
@Id
@GeneratedValue(generator = "increment_generator")
@GenericGenerator(name = "increment_generator",strategy = "increment")
private int id;
private String name;
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;
}
}
子类:
@Entity
@Table(name = "houremployee1")
@PrimaryKeyJoinColumn(name = "EMPLOYEEID")
public class HourEmployee extends Employee{
private Double rate;
public Double getRate() {
return rate;
}
public void setRate(Double rate) {
this.rate = rate;
}
@Override
public String toString() {
return "HourEmployee [rate=" + rate + ", getId()=" + getId() + ", getName()=" + getName() + "]";
}
}
三种映射方式的对比