Hibernate – 使用 XML 文件的每个层次结构的表
当对象保存在数据库中时, Hibernate能够将对象的继承属性及其新属性存储在其数据库中。在 Hibernate 中,当一个模块的多个 POJO 类包含一些公共属性时,会应用POJO类之间的继承。在实时应用中,Hibernate 的 POJO 类是基于数据库表设计的。如果不止一个 POJO 类具有一些公共属性,那么这些公共属性将被分离到一个称为基类的 POJO 类中,不常见的属性存储在派生类中。这就是Hibernate继承机制的概念。
Hibernate 继承映射
面向对象可以对“是一个”和“有一个”关系进行建模。关系模型仅支持两个实体之间的“具有”关系。 Hibernate 有助于将此类对象与关系表进行映射。 Hibernate 中定义了三种继承映射策略。
- 每个层次结构的表
- 每个混凝土类的表
- 每个子类的表
每个层次结构的表(XML 映射)
Table per Hierarchy是 hibernate 中的继承策略之一。在此策略中,整个层次结构映射到单个表。层次结构中所有类的所有属性都存储在一个表中。在每个层次结构策略的表中:
- 数据库中只创建了一张表,用于存储整个类层次结构的数据。
- Hibernate在数据库中存储了一个字符串,除了一个对象的数据,用于指示哪个派生类对象插入了该行数据。
- Hibernate 需要在表中添加一个称为鉴别器列的列,用于放置或存储子类对象的鉴别器值。
- 为了通知 Hibernate,我们在hbm.xml文件中的
> 标签下配置 标签。
在此策略中,空值将存储在没有适用列的表中。鉴别器唯一地标识类层次结构的基本类型。
每个层次结构的表策略示例
假设我们有一个Employee类,其子类为P_Employee 和 C_Employee 。以下是这些类的类图和关系。
我们有 3 个表Employee、P_Employee 和 C_Employee 。 Employee是P_Employee和C_Employee类的超类。我们会将所有 3 个类的所有属性存储在一个表中。
创建数据库表以保持类层次结构:
CREATE TABLE `Employee` (
`id` BIGINT(20) NOT NULL AUTO_INCREMENT,
`name` VARCHAR(50) NOT NULL DEFAULT ‘0’,
`age` BIGINT(3) NOT NULL DEFAULT ‘0’,
`salary` BIGINT(11) NULL DEFAULT NULL,
`hourlyrate` BIGINT(11) NULL DEFAULT NULL,
`duration` BIGINT(11) NULL DEFAULT NULL,
`discriminator` VARCHAR(20) NOT NULL,
PRIMARY KEY (`id`)
)
Employee表将存储所有三个类Employee、P_Employee 和 C_Employee的对象。
XML 映射的项目结构(IntelliJ IDEA):
为上述层次结构创建 Employee、P_Employee 和 C_Employee 类:
下面是Employee的实现。 Java文件:
Java
package com.exploit.model;
public class Employee {
private int id;
private String name;
private int age;
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; }
public int getAge() { return age; }
public void setAge(int age) { this.age = age; }
}
Java
package com.exploit.model;
public class P_Employee extends Employee {
private double salary;
public double getSalary() { return salary; }
public void setSalary(double salary)
{
this.salary = salary;
}
}
Java
package com.exploit.model;
public class C_Employee extends Employee {
private double hourlyRate;
private double duration;
public double getDuration() { return duration; }
public void setDuration(double duration)
{
this.duration = duration;
}
public double getHourlyRate() { return hourlyRate; }
public void setHourlyRate(double hourlyRate)
{
this.hourlyRate = hourlyRate;
}
}
XML
XML
com.mysql.jdbc.Driver
jdbc:mysql: //localhost/javainsimpleway
root
toor
1
org.hibernate.dialect.MySQLDialect
org.hibernate.cache.internal.NoCacheProvider
true
true
update
XML
4.0.0
TablePerHierarchyXML
TablePerHierarchyXML
0.0.1-SNAPSHOT
jar
TablePerHierarchyXML
http://maven.apache.org
UTF-8
junit
junit
3.8.1
test
org.hibernate
hibernate-core
5.2.6.Final
mysql
mysql-connector-java
6.0.5
Java
package com.exploit.db;
import com.exploit.model.C_Employee;
import com.exploit.model.Employee;
import com.exploit.model.P_Employee;
import com.exploit.util.HibernateUtil;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
public class Main {
public static void main(String[] args)
{
// Get session factory using Hibernate Util class
SessionFactory sessionFactory
= HibernateUtil.getSessionFactory();
// Get session from Sesson factory
Session session = sessionFactory.openSession();
// Begin transaction
Transaction transaction
= session.beginTransaction();
// Creating Employee base class record
Employee employee = new Employee();
employee.setName("KirikoChan");
employee.setAge(19);
// Creating Permanent Employee subclass record
P_Employee permanentEmployee = new P_Employee();
permanentEmployee.setName("Saili.H");
permanentEmployee.setAge(20);
permanentEmployee.setSalary(30000);
// Creating Contract Employee subclass record
C_Employee contractEmployee = new C_Employee();
contractEmployee.setName("ChikkoRita");
contractEmployee.setAge(18);
contractEmployee.setDuration(8.5);
contractEmployee.setHourlyRate(2000);
// persist all the employee records
session.persist(employee);
session.persist(permanentEmployee);
session.persist(contractEmployee);
// Commit the transaction and close the session
transaction.commit();
session.close();
System.out.println(
"Employee records successfully persisted.");
}
}
下面是P_Employee 的实现。 Java文件:
Java
package com.exploit.model;
public class P_Employee extends Employee {
private double salary;
public double getSalary() { return salary; }
public void setSalary(double salary)
{
this.salary = salary;
}
}
下面是C_Employee 的实现。 Java文件:
Java
package com.exploit.model;
public class C_Employee extends Employee {
private double hourlyRate;
private double duration;
public double getDuration() { return duration; }
public void setDuration(double duration)
{
this.duration = duration;
}
public double getHourlyRate() { return hourlyRate; }
public void setHourlyRate(double hourlyRate)
{
this.hourlyRate = hourlyRate;
}
}
为 Persistent 类创建映射文件:
下面是employee.hbm.xml文件的实现:
XML
我们只定义了一个休眠映射 (hbm) 文件employee.hbm.xml , P_Employee 和 C_Employee模型类都定义在一个hbm.xml文件中。
- “E”标识该记录属于Employee类。
- “PE”标识该记录属于P_Employee类。
- “CE”标识该记录属于C_Employee类。
Hibernate 将根据我们保留的记录放置适当的鉴别器值。
在hibernate配置文件中添加hbm.xml文件的映射:
下面是hibernate.cfg.xml文件的实现:
XML
com.mysql.jdbc.Driver
jdbc:mysql: //localhost/javainsimpleway
root
toor
1
org.hibernate.dialect.MySQLDialect
org.hibernate.cache.internal.NoCacheProvider
true
true
update
以下是 pom.xml 文件中使用的依赖项:
XML
4.0.0
TablePerHierarchyXML
TablePerHierarchyXML
0.0.1-SNAPSHOT
jar
TablePerHierarchyXML
http://maven.apache.org
UTF-8
junit
junit
3.8.1
test
org.hibernate
hibernate-core
5.2.6.Final
mysql
mysql-connector-java
6.0.5
创建存储持久对象的类:
下面是Main 的实现。 Java文件:
Java
package com.exploit.db;
import com.exploit.model.C_Employee;
import com.exploit.model.Employee;
import com.exploit.model.P_Employee;
import com.exploit.util.HibernateUtil;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
public class Main {
public static void main(String[] args)
{
// Get session factory using Hibernate Util class
SessionFactory sessionFactory
= HibernateUtil.getSessionFactory();
// Get session from Sesson factory
Session session = sessionFactory.openSession();
// Begin transaction
Transaction transaction
= session.beginTransaction();
// Creating Employee base class record
Employee employee = new Employee();
employee.setName("KirikoChan");
employee.setAge(19);
// Creating Permanent Employee subclass record
P_Employee permanentEmployee = new P_Employee();
permanentEmployee.setName("Saili.H");
permanentEmployee.setAge(20);
permanentEmployee.setSalary(30000);
// Creating Contract Employee subclass record
C_Employee contractEmployee = new C_Employee();
contractEmployee.setName("ChikkoRita");
contractEmployee.setAge(18);
contractEmployee.setDuration(8.5);
contractEmployee.setHourlyRate(2000);
// persist all the employee records
session.persist(employee);
session.persist(permanentEmployee);
session.persist(contractEmployee);
// Commit the transaction and close the session
transaction.commit();
session.close();
System.out.println(
"Employee records successfully persisted.");
}
}
这是使用XML映射Table Per Hierarchy的常用方法。