Hibernate每個層次類一張表(使用註釋)

在上一文章中,我們使用xml文件將繼承層次映射到一個表。 在這裏,我們將使用註釋來執行同樣的任務。需要使用[@Inheritance](https://github.com/Inheritance "@Inheritance")(strategy = InheritanceType.SINGLE_TABLE)[@DiscriminatorColumn](https://github.com/DiscriminatorColumn "@DiscriminatorColumn")[@DiscriminatorValue](https://github.com/DiscriminatorValue "@DiscriminatorValue")註釋,以便根據層次結構策略映射表。

在每個層次結構一張表的情況下,只需要一個表來映射繼承層次結構。 這裏,在表中創建一個額外的列(也稱爲discriminator列)來標識該類。

下面來看看看繼承層次結構:

Hibernate每個層次類一張表(使用註釋)

這個層次結構中有三個類。 EmployeeRegular_EmployeeContract_Employee類的父類。

此層次結構的表結構如下所示:

列名

數據類型

是否爲空

默認值

是否主鍵

id

int(10)

-

type

varchar(254)

-

-

name

varchar(254)

-

-

salary

float

-

-

bonus

int(10)

-

-

pay_per_hour

float

-

-

contract_duration

-

-

使用註釋的每個層次結構一張表示例

您需要按照以下步驟創建簡單示例:

  • 創建持久化類
  • 創建配置文件
  • 創建類來存儲提取數據

創建一個項目名稱爲:,其結構如下圖所示 -
Hibernate每個層次類一張表(使用註釋)

1)創建持久類

您需要創建表示繼承的持久化類。爲上面的層次結構創建三個類:

文件:Employee.java

package com.yiibai;

import javax.persistence.*;

@Entity  
@Table(name = "employee101")  
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)  
@DiscriminatorColumn(name="type",discriminatorType=DiscriminatorType.STRING)  
@DiscriminatorValue(value="employee")  
public class Employee {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id")
    private int id;

    @Column(name = "name")
    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;
    }

    // setters and getters
}

文件:Regular_Employee.java

package com.yiibai;

/**
 * 
 * @author by maxsu
 * @copyright http://www.yiibai.com
 * @link download at: http://www.yiibai.com/siteinfo/download.html
 */
import javax.persistence.*;

@Entity  
@DiscriminatorValue("regularemployee")  
public class Regular_Employee extends Employee {

    @Column(name = "salary")
    private float salary;

    @Column(name = "bonus")
    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;

/**
 * 
 * @author by maxsu
 * @copyright http://www.yiibai.com
 * @link download at: http://www.yiibai.com/siteinfo/download.html
 */
import javax.persistence.*;

@Entity  
@DiscriminatorValue("contractemployee")  
public class Contract_Employee extends Employee {

    @Column(name = "pay_per_hour")
    private float pay_per_hour;

    @Column(name = "contract_duration")
    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)在配置文件中添加持久化類

打開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 class="com.yiibai.Employee"/>  
        <mapping class="com.yiibai.Contract_Employee"/>   
        <mapping class="com.yiibai.Regular_Employee"/>   
    </session-factory>

</hibernate-configuration>

hbm2ddl.auto屬性定義是用於在數據庫中自動創建表。

3)創建存儲持久對象的類

在這個類中,我們只是將 Employee 對象存儲在數據庫中。
文件:MainTest.java

package com.yiibai;

import org.hibernate.*;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;

/**
 * 
 * @author by maxsu
 * @copyright http://www.yiibai.com
 * @link download at: http://www.yiibai.com/siteinfo/download.html
 */

public class MainTest {
    public static void main(String[] args) {
        // 但在5.1.0版本彙總,hibernate則採用如下新方式獲取:
        // 1. 配置類型安全的準服務註冊類,這是當前應用的單例對象,不作修改,所以聲明爲final
        // 在configure("cfg/hibernate.cfg.xml")方法中,如果不指定資源路徑,默認在類路徑下尋找名爲hibernate.cfg.xml的文件
        final StandardServiceRegistry registry = new StandardServiceRegistryBuilder()
                .configure("hibernate.cfg.xml").build();
        // 2. 根據服務註冊類創建一個元數據資源集,同時構建元數據並生成應用一般唯一的的session工廠
        SessionFactory sessionFactory = new MetadataSources(registry)
                .buildMetadata().buildSessionFactory();

        /**** 上面是配置準備,下面開始我們的數據庫操作 ******/
        Session session = sessionFactory.openSession();// 從會話工廠獲取一個session

        // creating transaction object
        Transaction t = session.beginTransaction();

        Employee e1 = new Employee();
        e1.setName("用戶名-01");

        Regular_Employee e2 = new Regular_Employee();
        e2.setName("yiibai su");
        e2.setSalary(50002);
        e2.setBonus(5);

        Contract_Employee e3 = new Contract_Employee();
        e3.setName("Mina su");
        e3.setPay_per_hour(1010);
        e3.setContract_duration("15 hours");

        session.persist(e1);
        session.persist(e2);
        session.persist(e3);

        t.commit();
        session.close();
        System.out.println("success");
    }
}

執行上面示例,輸出結果如下 -

log4j:WARN No appenders could be found for logger (org.jboss.logging).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
Sun Mar 26 02:19:13 CST 2017 WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification.
Sun Mar 26 02:19:14 CST 2017 WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification.
Hibernate: select next_val as id_val from hibernate_sequence for update
Hibernate: update hibernate_sequence set next_val= ? where next_val=?
Hibernate: select next_val as id_val from hibernate_sequence for update
Hibernate: update hibernate_sequence set next_val= ? where next_val=?
Hibernate: select next_val as id_val from hibernate_sequence for update
Hibernate: update hibernate_sequence set next_val= ? where next_val=?
Hibernate: insert into employee101 (name, type, id) values (?, 'employee', ?)
Hibernate: insert into employee101 (name, bonus, salary, type, id) values (?, ?, ?, 'regularemployee', ?)
Hibernate: insert into employee101 (name, contract_duration, pay_per_hour, type, id) values (?, ?, ?, 'contractemployee', ?)
success

查看數據表,應該會看到相應的數據記錄