类表继承模式(Class Table Inheritance Pattern)

19-06-10 jdon
                   

此模式属于对象关系结构模式目录,此目录属于企业应用程序体系结构模式

目的

表示类的继承层次结构,每个类具有一个表。类表继承在继承结构中为每个类支持一个数据库表。

说明

在图中,每个类都有自己的数据库表。

Player类有自己的玩家数据库表。

Cricketer类有自己的板球运动员数据库表。

Footballer类有自己的足球运动员数据库表。

Bowler类有自己的保龄球数据库表。

如何运作

关于类表继承,最直接的一点是在域模型中,每个类都有一个表。域类中的字段直接映射到相应表中的字段。与其他继承映射一样,继承映射器的基本方法也适用。

类表继承的最大实现问题是如何以有效的方式从多个表中返回数据。由于多次调用数据库,显然调用每个表并不好。您可以通过跨各种组件表进行连接来避免这种情况; 但是,由于数据库进行优化的方式,超过三个或四个表的连接往往速度很慢。 

何时使用它

类表继承,单表继承和具体表继承(Class Table Inheritance, Single Table Inheritance, and Concrete Table Inheritance )是继承映射需要考虑的三种方法。

类表继承的优点是:

  • 所有列都与每一行相关,因此表格更容易理解,不会浪费空间。

  • 域模型和数据库之间的关系非常简单。

类表继承的弱点是:

  • 您需要接触多个表来加载对象,这意味着一个连接或多个查询在内存中整合。

  • 任何对层次结构上下字段的重构都会导致数据库更改。

  • 父类型表可能会成为瓶颈,因为它们必须经常被访问。

  • 高度规范化可能使得即席查询难以理解。

  • 您不必为一个类层次结构选择一个继承映射模式。您可以对层次结构顶部的类使用类表继承, 为较低的层使用一组具体的表继承(Concrete Table Inheritance)

执行

Hibernate ORM Framework提供了继承映射策略:Table Per Concrete类使用Annotation

对于每个具体类的表,根据类创建表。但重复列被添加在子类表中。

对于Table Per Concrete类,每个类都创建表。因此表中没有可为空的值。这种方法的缺点是在子类表中创建了重复的列。

在这里,我们需要在父类中使用@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)注释,在子类中使用@AttributeOverrides注释。

@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)  指定我们使用每个具体类策略的表。它应该仅在父类中指定。

@AttributeOverrides  定义将在此类中重写父类属性。在表结构中,父类表列将添加到子类表中。

类层次结构如下:

创建Hibernate模型类。我们需要创建表示继承的持久类。让我们为上面的层次结构创建三个类:

import javax.persistence.*;  
  
@Entity  
@Table(name = "employee102")  
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)  
  
public class Employee {  
 @Id  
 @GeneratedValue(strategy=GenerationType.AUTO)  
    
 @Column(name = "id")  
 private int id;  
   
 @Column(name = "name")  
 private String name;  
   
 //setters and getters  
}  

import javax.persistence.*;  
  
@Entity  
@Table(name="regularemployee102")  
@AttributeOverrides({  
    @AttributeOverride(name="id", column=@Column(name="id")),  
    @AttributeOverride(name="name", column=@Column(name="name"))  
})  
public class Regular_Employee extends Employee{  
      
 @Column(name="salary")    
 private float salary;  
   
 @Column(name="bonus")     
 private int bonus;  
   
 //setters and getters  
}  

import javax.persistence.*;  
@Entity  
@Table(name="contractemployee102")  
@AttributeOverrides({  
    @AttributeOverride(name="id", column=@Column(name="id")),  
    @AttributeOverride(name="name", column=@Column(name="name"))  
})  
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;  
    }  
}  

在配置文件中添加 hbm 文件的映射-  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="dialect">org.hibernate.dialect.Oracle9Dialect</property>  
        <property name="connection.url">jdbc:oracle:thin:@localhost:1521:xe</property>  
        <property name="connection.username">system</property>  
        <property name="connection.password">oracle</property>  
<property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>  
          
        <mapping class="com.javatpoint.mypackage.Employee"/>  
        <mapping class="com.javatpoint.mypackage.Contract_Employee"/>  
        <mapping class="com.javatpoint.mypackage.Regular_Employee"/>  
    </session-factory>  
</hibernate-configuration>  

创建存储持久对象的类。在这个类中,我们只是将employee对象存储在数据库中。

文件:StoreData.java

import org.hibernate.*;  
import org.hibernate.cfg.*;  
  
public class StoreData {  
 public static void main(String[] args) {  
 AnnotationConfiguration cfg=new AnnotationConfiguration();  
 Session session=cfg.configure("hibernate.cfg.xml").buildSessionFactory().openSession();  
    
  Transaction t=session.beginTransaction();  
    
  Employee e1=new Employee();  
  e1.setName("sonoo");  
    
  Regular_Employee e2=new Regular_Employee();  
  e2.setName("Vivek Kumar");  
  e2.setSalary(50000);  
  e2.setBonus(5);  
    
  Contract_Employee e3=new Contract_Employee();  
  e3.setName("Arjun Kumar");  
  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");  
 }  
}