📜  Hibernate – 使用 XML 文件的每个层次结构的表

📅  最后修改于: 2022-05-13 01:54:21.808000             🧑  作者: Mango

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_EmployeeEmployeeP_EmployeeC_Employee类的超类。我们会将所有 3 个类的所有属性存储在一个表中。

创建数据库表以保持类层次结构:

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.xmlP_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的常用方法。