继承映射,是一种以继承关系进行实体映射的方式,描述的是父类与子类间的关系。继承映射分为三种方式:单表继承、所有类继承、子类继承。下面对这三种方式进行介绍。
实例:Cat和Dog继承自Animal类。(以下代码实体类中的get和set方法省略)
1、单表继承
即每棵类继承树一张表,将所有的信息都存放在一张表中,以整棵继承树为依据进行映射。
Animal类:
public class Ainmal { private int id; private String name; private String sex; }Cat类:
public class Cat extends Ainmal{ private String miao; }
Dog类:
public class Dog extends Ainmal{ private String bite; }Extends.hbm.xml映射文件:
<?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> <class name="com.tgb.hibernate.Ainmal" table="t_animal_extend1" lazy="true"> <id name="id"> <generator class="native" /> </id> <!-- 设置标记字段,区分Cat和Dog --> <discriminator column ="type" type="string"/> <property name="name"/> <property name="sex"/> <!-- 使用subclass标签来进行继承映射设置 --> <!-- name值表示子类,需要写全路径。 --> <!-- 使用discriminator-value属性类给不同的类进行标记 。对应会将值存在type字段上--> <subclass name="com.tgb.hibernate.Cat" discriminator-value="C"> <property name="miao"/> </subclass> <subclass name="com.tgb.hibernate.Dog" discriminator-value="D"> <property name="bite"/> </subclass> </class> </hibernate-mapping>注意:
1>使用subclass标签将子类关联到父类,进行映射。discriminator-value给区别字段赋值。
2>使用discriminator设置区别字段。
2、所有类继承
即父类和子类都生成表。实体类与第一种方式相同。
Extends.hbm.xml映射文件:
<?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.tgb.hibernate"> <class name="Ainmal" table="t_animal_extend2" > <id name="id"> <generator class="native" /> </id> <property name="name"/> <property name="sex"/> <!-- 使用joined-subclass标签进行设置继承关系 --> <joined-subclass name="Cat" table="t_cat_extend2"> <!-- 设置主键 --> <key column="cid"/> <property name="miao"/> </joined-subclass> <joined-subclass name="Dog" table="t_dog_extend2"> <key column="did"/> <property name="bite"/> </joined-subclass> </class> </hibernate-mapping>注意:
1>使用joined-subclass标签进行设置,同时设置主键。
3、子类继承
即每个子类一张表
Extends.hbm.xml映射文件:
<?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.tgb.hibernate"> <!-- 父类不再生成表,使用abstract属性设置成抽象 --> <class name="Ainmal" table="t_animal_extend3" abstract="true"> <id name="id"> <!-- 主键不能设置为自增 --> <generator class="assigned" /> </id> <property name="name"/> <property name="sex"/> <!-- 使用union-subclass标签进行映射 --> <union-subclass name="Cat" table="t_cat_extend3"> <property name="miao"/> </union-subclass> <union-subclass name="Dog" table="t_dog_extend3"> <property name="bite"/> </union-subclass> </class> </hibernate-mapping>注意:
1>使用abstract属性,将父类设置成抽象
2>此时主键不能使用自增
3>使用union-subclass标签进行映射的设置
三种映射的优缺点:
1、单表继承,一棵类继承树生成。使用时load默认支持lazy加载,但不支持多态查询。若将lazy设置为false,不支持延迟加载,可支持多态查询。 get和hql查询都可以支持多态查询。生成一张表,效率相对好,但是结构混乱,字段冗余。数据多时,效率也差
2、所有类继承,每个子类一个表。继承层次多时,表就会增多,效率降低。但是结构清晰,没有冗余。
3、子类继承:每个子类一张表。主键无法使用自增