之前的几篇文章主要介绍的是关系映射。之所以用好几篇的文章来介绍关系映射,其重要性与常用行可见一斑。还有一种映射,也就是今天要介绍的——继承映射,也是很重要的一种映射模式。
继承映射的实现有三种策略:
1、单表继承。每棵类继承树使用一个表。
2、具体表继承。每个子类一个表。
3、类表继承。每个具体类一个表。
下面将通过实例来具体说明这三种策略。我们以Animal类、Pig类、Bird类来讲解,三者的关系如下图:
虽然说是三种策略,但是他们都是继承映射,所以三个实体是不变的:子类(Pig、Bird)继承父类(Animal),并且具有自己特有的属性。
Animal类:
public class Animal { private int id; private String name; private Boolean sex; //省略各个属性的get、set方法 }
public class Bird extends Animal{
private int height;
//省略get、set方法
}
public class Pig extends Animal{ private int weight; //省略get、set方法 }
最终结果:只生成一个表,但是有一个鉴别字段:type
映射配置如下:Extends.hbm.xml
<hibernate-mapping> <class name="com.example.hibernate.Animal" table="t_animal"> <id name="id"> <generator class="native"/> </id> <discriminator column="type" type="string"></discriminator> <property name="name"/> <property name="sex"/> <subclass name="com.example.hibernate.Pig" discriminator-value="P"> <property name="weight"/> </subclass> <subclass name="com.example.hibernate.Bird" discriminator-value="B"> <property name="height"/> </subclass> </class> </hibernate-mapping>
最终结果:生成三个表。
每个表中的具体数据:
对应的映射配置:
<hibernate-mapping> <class name="com.example.hibernate.Animal" table="t_animal"> <id name="id"> <generator class="native"/> </id> <property name="name"/> <property name="sex"/> <joined-subclass name="com.example.hibernate.Pig" table="t_pig"> <key column="pid"/> <property name="weight"/> </joined-subclass> <joined-subclass name="com.example.hibernate.Bird" table="t_bird"> <key column="bid"/> <property name="height"/> </joined-subclass> </class> </hibernate-mapping>
最终结果:生成两个表
映射配置:
<hibernate-mapping> <class name="com.example.hibernate.Animal" table="t_animal" abstract="true"> <id name="id"> <generator class="assigned"/> </id> <property name="name"/> <property name="sex"/> <union-subclass name="com.example.hibernate.Pig" table="t_pig"> <property name="weight"/> </union-subclass> <union-subclass name="com.example.hibernate.Bird" table="t_bird"> <property name="height"/> </union-subclass> </class> </hibernate-mapping>
方式一:表中存在冗余字段。但是数据操作效率较高(都在同一张表中)。
方式二:层次非常清楚。但是如果继承层次太多的话,数据操作的效率明显不如方式一。
方式三:不能使用自增长,只能手动分配主键。
因此建议使用方式一。如果继承的层次很少,可以使用方式二。