在上一篇中,笔者向各位介绍了,Hibernate映射关系中的继承映射,其实说白了,就是将面向对象的思想,应用到表的设计当中去,本篇再介绍2个继承映射策略,读者可根据实际的需求而选择对应的继承策略
1.joined-subclass
简单介绍下这种继承映射的效果,父类的实例依然保存在父类表中,而子类实例中不属于父类属性的延展属性保存在子类表中,父类属性依旧保存在父类中,下面给出这类映射策略的xml配置。
<hibernate-mapping package="com.sooen.domain">
<!-- 映射Person类 -->
<class name="Person" table="person_inf">
<!-- 映射标识属性 -->
<id name="id" column="person_id">
<!-- 使用native的主键生成器策略 -->
<generator class="native"/>
</id>
<property name="name" type="java.lang.String" length="50">
<column name="name">
<comment>姓名</comment>
</column>
</property>
<property name="age" type="java.lang.String" length="50">
<column name="age">
<comment>年龄</comment>
</column>
</property>
<property name="sex" type="java.lang.String" length="50">
<column name="sex">
<comment>性别</comment>
</column>
</property>
<!-- 使用joined-subclass元素映射Person类的子类Employee -->
<joined-subclass name="Employee" >
<key>
<column name="emp_id"></column>
</key>
<!-- 映射一个基本属性 -->
<property name="position">
<column name="position">
<comment>职务</comment>
</column>
</property>
</joined-subclass>
</class>
</hibernate-mapping>
下面是控制台输出的建表语句
create table Employee (
emp_id varchar(255) not null,
position varchar(255) comment '职务',
primary key (emp_id)
) type=InnoDB
create table person_inf (
person_id varchar(255) not null auto_increment,
name varchar(255) comment '姓名',
age varchar(255) comment '年龄',
sex varchar(255) comment '性别',
primary key (person_id)
foreign key (emp_id)
references person_inf (person_id)
) type=InnoDB
分析一下这种映射策略下的建表语句与之前的subclass有什么不一样,在配置中,没有使用discriminator辨别者,但是有了外键关联的性质,从数据存储的角度来说,这种表设计可以减少数据库的冗余程度,增加数据库存储的利用率,但是从查询的角度而言,有了外键关联的表,若是查询子类的实例,则要进行多表查询,会影响其性能。
2.union-subclass
这种继承映射策略与上述的joined-subclass非常类似,唯一的不同是,父类实例存在父类表中,子类实例存在子类表中,子类表和父类表从数据库的角度而言,压根是看不出来有继承关系的,下面是这种映射机制的xml配置
<hibernate-mapping package="com.sooen.domain">
<!-- 映射Person类 -->
<class name="Person" table="person_inf">
<!-- 映射标识属性 -->
<id name="id" column="person_id">
</id>
<property name="name" type="java.lang.String" length="50">
<column name="name">
<comment>姓名</comment>
</column>
</property>
<property name="age" type="java.lang.String" length="50">
<column name="age">
<comment>年龄</comment>
</column>
</property>
<property name="sex" type="java.lang.String" length="50">
<column name="sex">
<comment>性别</comment>
</column>
</property>
<!-- 使用union-subclass元素映射Person类的子类Employee -->
<union-subclass name="Employee" table="emp_inf">
<!-- 映射一个基本属性 -->
<property name="position">
<column name="position">
<comment>职务</comment>
</column>
</property>
</union-subclass>
</class>
</hibernate-mapping>
create table emp_inf ( person_id varchar(255) not null, name varchar(255) comment '姓名', age varchar(255) comment '年龄', sex varchar(255) comment '性别', position varchar(255) comment '职务', primary key (person_id) ) type=InnoDB create table person_inf ( person_id varchar(255) not null, name varchar(255) comment '姓名', age varchar(255) comment '年龄', sex varchar(255) comment '性别', primary key (person_id) ) type=InnoDB
通过这个配置,反观之前的joined-subclass配置和上一篇的subclass配置,可以明显的发现,更加简洁了,没有采用外键关联,也没有采用辨别者列,不同的是没用使用id生成策略,笔者在测试的时候,发现设置了id生成策略之后,会出现问题,后来多方查阅资料才发现,再这类配置下,id是要统一管理起来的,不能使用数据库的生成策略,可以算是这个策略的一个缺憾吧。但是,反观这个配置的表结构,表和表之间没有外键相关联,实际中的父类和子类都是存在对应的表中的,这种生成策略更加符合数据库底层表的设计。而查询的时候,数据库都对数据进行union操作。 现在Hibernate的三种继承映射机制就写完了,subclass策略,展现了是对查询性能的提高,joined-subclass则是对数据冗余度进行了优化,union-subclass则更加符合底层的设计,读者可以根据自己的需求来进行相对应的策略配置。