Hibernate使用xml文件的每個類層次一張表
通過這種繼承策略,我們可以通過單表映射整個層次結構。 這裏,在表中創建一個額外的列(也稱爲discriminator
列)來標識該類。
讓我們先了解問題。下面給出的整個層次類映射到數據庫的一個表中圖解說明。
這個層次結構中有三個類。Employee
是Regular_Employee
和Contract_Employee
類的超類(父類)。 讓我們來看看這個層次結構類的映射文件。
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.yiibai.Employee" table="emp121"
discriminator-value="emp">
<id name="id">
<generator class="increment"></generator>
</id>
<discriminator column="type" type="string"></discriminator>
<property name="name"></property>
<subclass name="com.yiibai.Regular_Employee"
discriminator-value="reg_emp">
<property name="salary"></property>
<property name="bonus"></property>
</subclass>
<subclass name="com.yiibai.Contract_Employee"
discriminator-value="con_emp">
<property name="pay_per_hour"></property>
<property name="contract_duration"></property>
</subclass>
</class>
</hibernate-mapping>
在每個類層次結構一個表的情況下,hibernate框架添加了一個標識符列,該框架指定了記錄的類型。 它主要用於區分記錄。要指定它,必須指定類的 discriminator
子元素。
類的子類subelement
指定子類。 在這種情況下,Regular_Employee
和Contract_Employee
是Employee
類的子類。
此層次結構的表結構如下所示:
列名
數據類型
是否爲空
默認值
是否主鍵
id
int(10)
否
-
是
type
varchar(254)
否
-
-
name
varchar(254)
是
-
-
salary
float
是
-
-
bonus
int(10)
是
-
-
pay_per_hour
float
是
-
-
contract_duration
是
-
-
每個類層次結構一個表示例
在這個例子中,我們創建了三個類,並在employee.hbm.xml
文件中提供了這些類的映射。
完整的工程目錄如下所示 -
下載代碼的項目名稱:table-per-hierarchy-example-using-xml-file
1)創建持久類
您需要創建表示繼承的持久化類。讓我們爲上面的層次結構創建三個類:
文件: Employee.java
package com.yiibai;
public class Employee {
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;
}
}
文件: Regular_Employee.java
package com.yiibai;
public class Regular_Employee extends Employee {
private float salary;
private int bonus;
public float getSalary() {
return salary;
}
public void setSalary(float salary) {
this.salary = salary;
}
public int getBonus() {
return bonus;
}
public void setBonus(int bonus) {
this.bonus = bonus;
}
}
文件: Contract_Employee.java
package com.yiibai;
public class Contract_Employee extends Employee {
private float pay_per_hour;
private String contract_duration;
public float getPay_per_hour() {
return pay_per_hour;
}
public void setPay_per_hour(float payPerHour) {
pay_per_hour = payPerHour;
}
public String getContract_duration() {
return contract_duration;
}
public void setContract_duration(String contractDuration) {
contract_duration = contractDuration;
}
}
2)創建持久化類的映射文件
上面我們已經瞭解了層次結構,下面來看看如何配置映射文件。
文件: employee.hbm.xml
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.yiibai.Employee" table="emp121"
discriminator-value="emp">
<id name="id">
<generator class="increment"></generator>
</id>
<discriminator column="type" type="string"></discriminator>
<property name="name"></property>
<subclass name="com.yiibai.Regular_Employee"
discriminator-value="reg_emp">
<property name="salary"></property>
<property name="bonus"></property>
</subclass>
<subclass name="com.yiibai.Contract_Employee"
discriminator-value="con_emp">
<property name="pay_per_hour"></property>
<property name="contract_duration"></property>
</subclass>
</class>
</hibernate-mapping>
3)在配置文件中添加hbm文件的映射
打開hibernate.cfg.xml
文件,並添加如下映射資源的條目:
<mapping resource="employee.hbm.xml"/>
現在配置文件將如下所示:
文件:hibernate.cfg.xml
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<!-- Generated by MyEclipse Hibernate Tools. -->
<hibernate-configuration>
<session-factory>
<property name="hbm2ddl.auto">update</property>
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost:3306/test</property>
<property name="connection.username">root</property>
<property name="connection.password">123456</property>
<property name="dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property>
<property name="show_sql">true</property>
<mapping resource="employee.hbm.xml"/>
</session-factory>
</hibernate-configuration>
hbm2ddl.auto
屬性定義是用於在數據庫中創建自動錶。
4)創建存儲持久對象的類
在這個類中,我們只是將Employee
對象存儲到數據庫表中。
文件:StoreData.java
package com.yiibai;
import org.hibernate.*;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.*;
public class StoreData {
public static void main(String[] args) {
// Session session = new
// AnnotationConfiguration().configure().buildSessionFactory().openSession();
final StandardServiceRegistry registry = new StandardServiceRegistryBuilder()
.configure("hibernate.cfg.xml").build();
// 2. 根據服務註冊類創建一個元數據資源集,同時構建元數據並生成應用一般唯一的的session工廠
SessionFactory sessionFactory = new MetadataSources(registry)
.buildMetadata().buildSessionFactory();
/**** 上面是配置準備,下面開始我們的數據庫操作 ******/
Session session = sessionFactory.openSession();// 從會話工廠獲取一個session
Transaction t = session.beginTransaction();
Employee e1 = new Employee();
e1.setName("Yiibai");
Regular_Employee e2 = new Regular_Employee();
e2.setName("Max su");
e2.setSalary(50000);
e2.setBonus(5);
Contract_Employee e3 = new Contract_Employee();
e3.setName("Hippo su");
e3.setPay_per_hour(1000);
e3.setContract_duration("15 hours");
session.persist(e1);
session.persist(e2);
session.persist(e3);
t.commit();
session.close();
System.out.println("success");
}
}
運行上面程序,並打數據庫表查看執行結果。