Hibernate – 使用 XML 文件的每个具体类的表
当对象保存在数据库中时, Hibernate能够将对象的继承属性及其新属性存储在其数据库中。在 Hibernate 中,当一个模块的多个 POJO 类包含一些公共属性时,会应用POJO类之间的继承。在实时应用中,Hibernate 的 POJO 类是基于数据库表设计的。
如果多个 POJO 类具有一些公共属性,那么这些公共属性将被分离到称为基类的 POJO 类中,不常见的属性存储在派生类中。这就是Hibernate继承机制的概念。 Hibernate 能够根据数据库设计将应用程序的类层次结构的数据存储到数据库的一个表或数据库的多个表中。
Hibernate 继承映射
面向对象可以对“是一个”和“有一个”关系进行建模。关系模型仅支持两个实体之间的“具有”关系。 Hibernate 有助于将此类对象与关系表进行映射。 Hibernate 中定义了三种继承映射策略。
- 每个层次结构的表
- 每个混凝土类的表
- 每个子类的表
每个具体类的表(XML 映射)
Table per Concrete Class是 hibernate 中的继承策略之一。如果我们想将继承的每个具体类对象保留在数据库的单独表中,那么我们可以继续使用每个具体类策略的表。
在每个具体类策略的表中:
- Hibernate 将层次结构的每个派生类对象存储在数据库的单独表中。
- 为了通知hibernate每个具体的类继承映射应用表,我们需要在hbm.xml文件的
标签下配置 标签。 - 鉴别器列是可选的。
在此策略中,每个子类表将具有子类特定属性和从父类继承的属性。
每个具体类策略的表示例:
假设我们有一个 Employee 类,其子类为 P_Employee 和 C_Employee。以下是这些类的类图和关系。
我们有 3 个表Employee、P_Employee和C_Employee。子类的映射重复了父类的属性。
创建数据库表以持久化具体类:
CREATE TABLE `Employee` (
`Id` BIGINT(20) NOT NULL AUTO_INCREMENT,
`name` VARCHAR(50) NOT NULL DEFAULT ‘0’,
`age` BIGINT(3) NOT NULL DEFAULT ‘0’,
PRIMARY KEY (`id`)
)
CREATE TABLE `P_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,
PRIMARY KEY (`id`)
)
CREATE TABLE `C_Employee` (
`Id` BIGINT(20) NOT NULL AUTO_INCREMENT,
`name` VARCHAR(50) NOT NULL DEFAULT ‘0’,
`age` BIGINT(3) NOT NULL DEFAULT ‘0’,
`hourlyrate` BIGINT(11) NULL DEFAULT NULL,
`duration` BIGINT(11) NULL DEFAULT NULL,
PRIMARY KEY (`id`)
)
XML 映射的项目结构(IntelliJ IDEA):
创建员工 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(String city) { 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 void setDuration(double duration)
{
this.duration = duration;
}
public double getDuration() { return duration; }
public double getHourlyRate() { return hourlyRate; }
public void setHourlyRate(double hourlyRate)
{
this.hourlyRate = hourlyRate;
}
}
XML
/*package whatever //do not write package name here */
XML
com.mysql.jdbc.Driver
jdbc:mysql://localhost/javainsimpleway
root
root
1
org.hibernate.dialect.MySQLDialect
org.hibernate.cache.internal.NoCacheProvider
true
true
update
下面是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 void setDuration(double duration)
{
this.duration = duration;
}
public double getDuration() { return duration; }
public double getHourlyRate() { return hourlyRate; }
public void setHourlyRate(double hourlyRate)
{
this.hourlyRate = hourlyRate;
}
}
为 Persistent 类创建映射文件:
下面是employee.hbm.xml文件的实现
XML
/*package whatever //do not write package name here */
在hibernate配置文件中添加hbm.xml文件的映射:
下面是hibernate.cfg.xml文件的实现
XML
com.mysql.jdbc.Driver
jdbc:mysql://localhost/javainsimpleway
root
root
1
org.hibernate.dialect.MySQLDialect
org.hibernate.cache.internal.NoCacheProvider
true
true
update
我们只定义了一个休眠映射 (hbm) 文件Employee.hbm.xml, P_Employee 和 C_Employee 模型类都定义在一个hbm.xml文件中。我们在 hbm 中使用一个简单的