Java程序员从笨鸟到菜鸟之(五十五)细谈Hibernate(六)Hiberna

在面向对象的程序领域中,类与类之间是有继承关系的,例如Java世界中只需要extends关键字就可以确定这两个类的父子关系,但是在关系数据库的世界 中,表与表之间没有任何关键字可以明确指明这两张表的父子关系,表与表是没有继承关系这样的说法的。为了将程序领域中的继承关系反映到数据 中,Hibernate为我们提供了3中方案:

第一种方案:一个子类对应一张表。

第二种方案:使用一张表表示所有继承体系下的类的属性的并集。

第三种方案:每个子类使用一张表只存储它特有的属性,然后与父类所对应的表以一对一主键关联的方式关联起来。

这三种方案用官方的语言来说就是:

TPS:每个子类一个表(table per subclass) 。

TPH:每棵类继承树使用一个表(table per class hierarchy)

TPC:类表继承。每个具体类一个表(table per concrete class)(有一些限制)

现在我们就根据一个实例来看一下这三种方案的各自优缺点,一起来熟悉一下这三种方案。现在假设有People、Student、Teacher三个类,父类为People,Student与Teacher为People的父类,代码如下:

People类:

public class People{/*父类所拥有的属性*/private Stringid;private Stringname;private Stringsex;private Stringage;private Timestampbirthday;/*get和set方法*/}Student类:public class Student extends People{/*学生独有的属性*/private String cardId;//学号public String getCardId(){ return cardId;}public void setCardId(String cardId){this.cardId = cardId;}}Teacher类:public class Teacher extends People{/*Teacher所独有的属性*/privateint salary;//工资public int getSalary(){return salary;}public void setSalary(int salary){this.salary = salary;}}

第一种方案:一个子类对应一张表(TPS)

该方案是使继承体系中每一个子类都对应数据库中的一张表。示意图如下:

  每一个子类对应的数据库表都包含了父类的信息,并且包含了自己独有的属性。每个子类对应一张表,而且这个表的信息是完备的,即包含了所有从父类继承下来的属性映射的字段。这种策略是使用<union-subclass>标签来定义子类的。

配置People.hbm.xml文件:

<?xml version="1.0"encoding="utf-8"?><!DOCTYPE hibernate-mapping PUBLIC"-//Hibernate/Hibernate Mapping DTD 3.0//EN"""><hibernate-mapping><class name="com.bzu.hibernate.pojos.People"abstract="true"><id name="id" type="string"><column name="id"></column><generator class="uuid"></generator></id><property name="name" column="name"type="string"></property><property name="sex" column="sex"type="string"></property><property name="age" column="age"type="string"></property><property name="birthday" column="birthday"type="timestamp"></property><!–<union-subclass name="com.bzu.hibernate.pojos.Student"table="student"><property name="cardId" column="cardId"type="string"></property></union-subclass><union-subclass name="com.bzu.hibernate.pojos.Teacher"table="teacher"><property name="salary" column="salary"type="integer"></property></union-subclass>–></class><union-subclass name="com.bzu.hibernate.pojos.Student"table="student"extends="com.bzu.hibernate.pojos.People"><property name="cardId" column="cardId"type="string"></property></union-subclass><union-subclass name="com.bzu.hibernate.pojos.Teacher"table="teacher"extends="com.bzu.hibernate.pojos.People"><property name="salary" column="salary"type="integer"></property></union-subclass></hibernate-mapping>以上配 置是一个子类一张表方案的配置,<union-subclass>标签是用于指示出该hbm文件所表示的类的子类,如People类有两个子 类,就需要两个<union-subclass>标签以此类推。<union-subclass>标签的"name"属性用于指 定子类的全限定名称,"table"属性用于指定该子类对应的表的名称,"extends"属性用于指定该子类的父类,注意该属性与<union-subclass>标签的位置有关,若<union-subclass>标签作为<class>标签的子标签,则"extends"属性可以不设置,否则需要明确设置"extends"属性。<class>标签中的"abstract"属性如果值为true则,不会生成表结构。如果值为false则会生成表结构,但是不会插入数据。

你可以很有个性,但某些时候请收敛。

Java程序员从笨鸟到菜鸟之(五十五)细谈Hibernate(六)Hiberna

相关文章:

你感兴趣的文章:

标签云: