Hibernate提供了几种策略来处理继承关系,主要有三种:
- 单表继承(Single Table Inheritance):在单个表中存储继承层次结构的所有类。
- 表连接继承(Joined Table Inheritance):为每个类创建独立的表,并使用外键建立关联。
- 表每类继承(Table Per Class Inheritance):为每个具体类创建独立的表,不存储父类信息。
下面详细介绍这三种策略,并通过具体的示例代码演示如何在Hibernate中实现它们。
单表继承(Single Table Inheritance)
在单表继承策略中,继承层次结构的所有类的属性和数据都存储在同一个表中,通过一个区分列(discriminator column)来区分具体的类型。
示例
配置文件 hibernate.cfg.xml
xml
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">com.mysql.cj.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/your_database</property>
<property name="hibernate.connection.username">your_username</property>
<property name="hibernate.connection.password">your_password</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.show_sql">true</property>
<property name="hibernate.format_sql">true</property>
<property name="hibernate.hbm2ddl.auto">update</property>
<mapping class="com.example.domain.Person"/>
<mapping class="com.example.domain.Employee"/>
<mapping class="com.example.domain.Student"/>
</session-factory>
</hibernate-configuration>
实体类
父类 Person
java
package com.example.domain;
import javax.persistence.*;
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "person_type", discriminatorType = DiscriminatorType.STRING)
public abstract class Person {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
// constructors, getters, and setters
public Person() {}
public Person(String name) {
this.name = name;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
子类 Employee
java
package com.example.domain;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
@Entity
@DiscriminatorValue("EMPLOYEE")
public class Employee extends Person {
private double salary;
// constructors, getters, and setters
public Employee() {}
public Employee(String name, double salary) {
super(name);
this.salary = salary;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
}
子类 Student
java
package com.example.domain;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
@Entity
@DiscriminatorValue("STUDENT")
public class Student extends Person {
private String major;
// constructors, getters, and setters
public Student() {}
public Student(String name, String major) {
super(name);
this.major = major;
}
public String getMajor() {
return major;
}
public void setMajor(String major) {
this.major = major;
}
}
插入和查询示例代码
java
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
public class HibernateSingleTableInheritanceExample {
public static void main(String[] args) {
// 获取SessionFactory
SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
// 插入数据
insertSampleData(sessionFactory);
// 查询数据
queryData(sessionFactory);
// 关闭SessionFactory
sessionFactory.close();
}
private static void insertSampleData(SessionFactory sessionFactory) {
Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
try {
Employee employee = new Employee("John Doe", 50000.0);
Student student = new Student("Jane Doe", "Computer Science");
session.save(employee);
session.save(student);
transaction.commit();
} catch (Exception e) {
if (transaction != null) {
transaction.rollback();
}
e.printStackTrace();
} finally {
if (session != null) {
session.close();
}
}
}
private static void queryData(SessionFactory sessionFactory) {
Session session = sessionFactory.openSession();
try {
List<Person> persons = session.createQuery("FROM Person", Person.class).list();
for (Person person : persons) {
System.out.println("Person: " + person.getName());
if (person instanceof Employee) {
System.out.println("Employee Salary: " + ((Employee) person).getSalary());
} else if (person instanceof Student) {
System.out.println("Student Major: " + ((Student) person).getMajor());
}
}
} finally {
if (session != null) {
session.close();
}
}
}
}
表连接继承(Joined Table Inheritance)
在表连接继承策略中,为每个类创建独立的表,子类表包含自己的属性并通过外键引用父类表中的记录。
示例
实体类
父类 Person
java
package com.example.domain;
import javax.persistence.*;
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public abstract class Person {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
// constructors, getters, and setters
public Person() {}
public Person(String name) {
this.name = name;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
子类 Employee
java
package com.example.domain;
import javax.persistence.Entity;
@Entity
public class Employee extends Person {
private double salary;
// constructors, getters, and setters
public Employee() {}
public Employee(String name, double salary) {
super(name);
this.salary = salary;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
}
子类 Student
java
package com.example.domain;
import javax.persistence.Entity;
@Entity
public class Student extends Person {
private String major;
// constructors, getters, and setters
public Student() {}
public Student(String name, String major) {
super(name);
this.major = major;
}
public String getMajor() {
return major;
}
public void setMajor(String major) {
this.major = major;
}
}
查询和插入数据的代码与单表继承的示例相同。
表每类继承(Table Per Class Inheritance)
在表每类继承策略中,每个具体类都有自己的独立表,不存储父类信息,所有字段(包括父类的字段)都在子类表中。
示例
实体类
父类 Person
java
package com.example.domain;
import javax.persistence.*;
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class Person {
@Id
@GeneratedValue(strategy = GenerationType.TABLE)
private Long id;
private String name;
// constructors, getters, and setters
public Person() {}
public Person(String name) {
this.name = name;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
子类 Employee
java
package com.example.domain;
import javax.persistence.Entity;
@Entity
public class Employee extends Person {
private double salary;
// constructors, getters, and setters
public Employee() {}
public Employee(String name, double salary) {
super(name);
this.salary = salary;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
}
子类 Student
java
package com.example.domain;
import javax.persistence.Entity;
@Entity
public class Student extends Person {
private String major;
// constructors, getters, and setters
public Student() {}
public Student(String name, String major) {
super(name);
this.major = major;
}
public String getMajor() {
return major;
}