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


在上一文章中,我們使用xml檔案將繼承層次對映到一個表。 在這裡,我們將使用注釋來執行同樣的任務。需要使用@Inheritance(strategy = InheritanceType.SINGLE_TABLE)@DiscriminatorColumn@DiscriminatorValue注釋,以便根據層次結構策略對映表。

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

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

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

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

列名 資料型別 是否為空 預設值 是否主鍵
id int(10) -
type varchar(254) - -
name varchar(254) - -
salary float - -
bonus int(10) - -
pay_per_hour float - -
contract_duration - -

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

您需要按照以下步驟建立簡單範例:

  • 建立持久化類
  • 建立組態檔案
  • 建立類來儲存提取資料

建立一個專案名稱為:,其結構如下圖所示 -

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 https://www.tw511.com
 * @link download at: https://www.tw511.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 https://www.tw511.com
 * @link download at: https://www.tw511.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 https://www.tw511.com
 * @link download at: https://www.tw511.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

檢視資料表,應該會看到相應的資料記錄