Hibernate映射之“继承映射”--subclass

来源:互联网 发布:开设网络教育的学校 编辑:程序博客网 时间:2024/06/06 08:55

这是我的第一篇技术博客,写的不好,还请大家多多包涵,这就当做我的一个职业学习之路的开卷篇。

我个人觉得,每次做个技术方面的博文,一般得先引出一些问题,博文来解决这些问题,这样的博文,才算的上好的博文,如果只是空洞的讲技术,只怕有些虚心求教的人,看着也有些许乏味吧。

应该是上上周吧,我同事他负责的一个项目,我帮他做测试,进首页的时候,我就发现特别慢,应该是从服务器读取数据库里的数据的效率低下的原因,于是就跟同事说,这查询应该还能优化吧?他跟我说,优化不了,我还是用我的垃圾电脑当服务器跑的,能有这效率就挺不错了,同事后来告诉我,这些数据全部都是从一张业务表读出来的,总共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映射机制的讲解。

(后记:这是笔者的第一篇技术性博客,写的好或者不好,多请大家提出意见,多多批评……谢谢)


 

0 0