这是我的第一篇技术博客,写的不好,还请大家多多包涵,这就当做我的一个职业学习之路的开卷篇。
我个人觉得,每次做个技术方面的博文,一般得先引出一些问题,博文来解决这些问题,这样的博文,才算的上好的博文,如果只是空洞的讲技术,只怕有些虚心求教的人,看着也有些许乏味吧。
应该是上上周吧,我同事他负责的一个项目,我帮他做测试,进首页的时候,我就发现特别慢,应该是从服务器读取数据库里的数据的效率低下的原因,于是就跟同事说,这查询应该还能优化吧?他跟我说,优化不了,我还是用我的垃圾电脑当服务器跑的,能有这效率就挺不错了,同事后来告诉我,这些数据全部都是从一张业务表读出来的,总共37w条数据,而这个项目的业务表,也只有那么一张,我当时听了就目瞪口呆的(请原谅刚入职的菜鸟)。这时候同事就给我讲了,这个表结构来自于Hibernate的继承映射。
说了这么多废话,下面就进入正题。
首先讲,如何实现刚刚所说的,多个持久化类所映射的表为一张。我们来举例一下,person这个类,基本属性有:姓名,年龄,性别。Employee这个类基本属性有:姓名,年龄,性别,职位。 看到这里,聪明的读者一定会知道,这是有继承关系的2个类。
/**
* 基础类-人
* @author S3
*
*/
public class Person implements Serializable {
/**
* 序列号
*/
private static final long serialVersionUID = 1L;
/**
* 主键
*/
private String id;
/**
* 姓名
*/
private String name;
/**
* 年龄
*/
private String age;
/**
* 性别
*/
private String sex;
public class Employee extends Person {
/**
* 序列号
*/
private static final long serialVersionUID = 1L;
/**
* 职位
*/
private String position;
现在就是这个继承映射的关键了,在xml中的配置
<hibernate-mapping package="com.sooen.domain">
<!-- 映射Person类 -->
<class name="Person" table="person_inf" discriminator-value="普通人">
<!-- 映射标识属性 -->
<id name="id" column="person_id">
<!-- 使用native的主键生成器策略 -->
<generator class="native"/>
</id>
<!-- 映射辨别属性 -->
<discriminator>
<column name="quf">
<comment>辨别字段</comment>
</column>
</discriminator>
<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>
<!-- 使用subclass元素映射Person类的子类Employee -->
<subclass name="Employee" discriminator-value="雇员">
<!-- 映射两个基本属性 -->
<property name="position">
<column name="position">
<comment>职务</comment>
</column>
</property>
</subclass>
</class>
</hibernate-mapping>
咋一看,挺简单的吧,与平时的配置没什么不同,就是多了2个元素,subclass,discriminator,subclass 的用法和class没什么不同,只是每个subclass下的类映射都要加上discriminator辨别者的值,如下是控制台自动的建表语句。
create table person_inf (
person_id varchar(255) not null auto_increment,
quf varchar(255) not null comment '辨别字段',
name varchar(255) comment '姓名',
age varchar(255) comment '年龄',
sex varchar(255) comment '性别',
position varchar(255) comment '职务',
primary key (person_id)
) type=InnoDB
技术层的实现,我们已经全然了解,现在我们来讨论下,为什么要采用这种映射机制?先说下这种映射机制的缺憾,这种映射机制下,所有子类的字段都不能有非空约束,增加非空约束的话,父类的实例则无法保存到表中,数据保存的时候,会导致表中存在许多的null,造成一定的数据冗余;再来谈谈这种映射机制的优点,因为整个继承全部都在一张表中,所以不管怎么查,查那一个继承树下的实体类,都只需要完成单表查询即可,避免了多表连接查询,union查询,性能方面就有了相对应的提升。
但是对于Hibernate的继承映射机制,可不止这么一种,还有join-subclass与union-subclass,这个请关注下一篇hibernate映射机制的讲解。
(后记:这是笔者的第一篇技术性博客,写的好或者不好,多请大家提出意见,多多批评……谢谢)