今天这篇博客,说的是hibernate的继承映射。
刚听到继承映射的时候,不知道是怎么一回事。视频看完,哦,原来我使用过。没有学习过ORM之类知识的孩子们,如果是第一次听说,不要担心,你们一定使用过,只是不知道它用过这样一个名称而已。看下面的表:
这样的表结构,是不是很熟悉的。这就是继承映射的一种。
特点:
1、表中存放了几种不同类型的数据
2、他们用“Type”字段来区分。
3、字段有公用的,有特殊的。
公用的就是:name,sex ,但是有些字段是针对某种数据而存在的,所以数据库中有写字典为“空”。例如:heigth 是针对“小鸟鸟”,而weight 是针对“小猪猪”的。
继承映射不光只有这一种形式,我们来看看继承映射的形式。
二、继承映射
什么继承映射?要说继承映射之前,得先说说继承映射的由来。大家知道在面向对象的程序领域中,类与类之间是有继承关系的,例如Java世界中只需要extends关键字就可以确定这两个类的父子关系,但是在关系数据库的世界中,表与表之间没有任何关键字可以明确指明这两张表的父子关系,表与表是没有继承关系这样的说法的。为了将程序领域中的继承关系反映到数据中,Hibernate为我们提供了三种方案,分别是:
1:一颗继承树一张表。
2:一个类对应一张表。
3:每个具体子类使用一张表。
我们先看 继承关系类图,这就是一颗继承树。
通过这颗树,来理解这三种表现形式。
首先是第一种:使用一张表表示所有继承体系下的类的属性的并集。
这种策略是使用<subclass>标签来实现的。因为类继承体系下会有许多个子类,要把多个类的信息存放在一张表中,必须有某种机制来区分哪些记录是属于哪个类的。Hibernate中的这种机制就是,在表中添加一个字段,用这个字段的值来进行区分。在表中添加这个标示列使用<discriminator>标签来实现。这也是第一篇中提到的“例子”。Animal,Pig,Bird都映射到一张表中。
hbm.xml 如下:
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="com.bjpowernode.hibernate"> <span style="color:#FF0000;"><class name="Animal</span>" table="t_animal" lazy="false"> <id name="id"> <generator class="native"/> </id> <span style="color:#FF0000;"><discriminator</span> column="type" type="string"/> <property name="name"/> <property name="sex"/> <span style="color:#FF0000;"><subclass</span> name="Pig" discriminator-value="P"> <property name="weight"/> </subclass> <span style="color:#FF6666;"><subclass </span>name="Bird" discriminator-value="B"> <property name="height"/> </subclass> </class> </hibernate-mapping>
其次是第二种:一个类一张表:上图中继承树,就可以被映射成三个表;
这种策略是使用<joined-subclass>标签来定义子类的。父类、子类都对应一张数据库表。在父类对应的数据库表中,它存储了所有记录的公共信息,实际上该父类对应的表会包含所有的记录,包括父类和子类的记录;在子类对应的数据库表中,这个表只定义了子类中所特有的属性映射的字段。子类对应的数据表与父类对应的数据表,通过一对一主键关联的方式关联起来。
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="com.bjpowernode.hibernate"> <<span style="color:#FF0000;">class name="Animal"</span> table="t_animal"> <id name="id"> <generator class="native"/> </id> <property name="name"/> <property name="sex"/> <span style="color:#FF0000;"><joined-subclass</span> name="Pig" table="t_pig"> <key column="pid"/> <property name="weight"/> </joined-subclass> <span style="color:#FF0000;"><joined-subclass</span> name="Bird" table="t_bird"> <key column="bid"/> <property name="height"/> </joined-subclass> </class> </hibernate-mapping>
最后是每个具体子类一张表:每一个子类对应的数据库表都包含了父类的信息,并且包含了自己独有的属性。每个子类对应一张表,而且这个表的信息是完备的,即包含了所有从父类继承下来的属性映射的字段。这种策略是使用<union-subclass>标签来定义子类的。
<span style="font-family:KaiTi_GB2312;font-size:18px;"><?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="com.bjpowernode.hibernate"> <<span style="color:#FF0000;">class name</span>="Animal" table="t_animal" <span style="color:#FF0000;">abstract="true</span>"> <id name="id"> <generator class="assigned"/> </id> <property name="name"/> <property name="sex"/> <span style="color:#FF0000;"><union-subclass</span> name="Pig" table="t_pig"> <property name="weight"/> </union-subclass> <span style="color:#FF0000;"><union-subclass</span> name="Bird" table="t_bird"> <property name="height"/> </union-subclass> </class> </hibernate-mapping></span>
三种映射形式简单对比
一句话:具体情况具体分析。