此模式属于对象关系结构模式目录,此目录属于企业应用程序体系结构模式。
目的
表示类的继承层次结构,每个类具有一个表。类表继承在继承结构中为每个类支持一个数据库表。
说明
在图中,每个类都有自己的数据库表。
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"); } } |