Hibernate(七)——继承映射

来源:互联网 发布:windows gif 录制 编辑:程序博客网 时间:2024/06/06 11:43

通过前面几篇文章,介绍了关联映射的一些概念。在实际应用中,关联映射用到的最多。除此之外,还会较多的用到本文讲到的继承映射。

实现继承映射,主要有三种策略:单表继承、具体表继承和类表继承。

单表继承——每棵继承树使用一个表;

具体表继承——每一个类分别使用一个表;

类表继承——每个具体类分别使用一个表。


看下图集成结构:Pig和Bird都属于Animal,并且Pig和Bird都分别有自己特有的属性。分下使用三种继承映射对它进行实现。



继承映射无论采用三种策略中的哪一种,实体类均是一样的。子类继承父类Animal,并各自拥有各自的属性。这里不做过多介绍。


1、每棵继承树使用一张表的映射


此种映射方式,在数据库中,只生成一个表。此外,表中会多一个鉴别字段:

映射方式:

<?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.lzq.hibernate"><class name="Animal" table="t_animal" lazy="true"><id name="id"><generator class="native" /></id><!-- 此处为在配置中加的鉴别字段,用于对Pig和Bird做出区分--><discriminator column="type" type="string"/><property name="name" /><property name="sex" /><!-- 当discriminator的值为P时,为Pig,特有属性为weight--><subclass name="Pig" discriminator-value="P"><property name="weight" /></subclass><!-- 当discriminator的值为P时,为Pig,特有属性为height--><subclass name="Bird" discriminator-value="B"><property name="height" /></subclass></class></hibernate-mapping>


显然,该种策略,对少量数据的查询有着得天独厚的优势,只有一张表,节约查询时间,简单易行。而缺点就是存在冗余字段,而且面对大数据量,就会显得有些吃力。


2、每个类一张表使用一张表的映射


该种映射方式,映射的结果,有几个类,就会生成几个表。因此,在此例中会生成三个表:

映射方式:

<?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.lzq.hibernate"><class name="Animal" table="t_animal"><id name="id"><generator class="native" /></id><property name="name" /><property name="sex" /><!--              每个类使用一张表:每个<joined-subclass>标签生成一张表,             <joined-subclass>标签下的<key>标签映射成主键,<property>映射成字段        --><joined-subclass name="Pig" table="t_pig"><key column="pid" /><property name="weight" /></joined-subclass><!--  同上--><joined-subclass name="Bird" table="t_bird"><key column="bid" /><property name="height" /></joined-subclass></class></hibernate-mapping>


该种映射方式不存在数据冗余,但是每次查询,最少查询两张表。


3、每个具体类一张表的映射


本例中存在两个具体类,即会映射成两张表:



映射方式:


<?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.lzq.hibernate"><!-- 需要在class标签上设置abstract为true,不然会生成Animal表 --><class name="Animal" table="t_animal" abstract="true"><!-- 主键生成策略必须采用手动赋值的方式--><id name="id"><generator class="assigned" /></id><property name="name" /><property name="sex" /><!--              每个具体类一张表:只有每个<union-subclass>标签会生成一张表有意义的表,            <property>标签映射成特有字段        --><union-subclass name="Pig" table="t_pig"><property name="weight" /></union-subclass><!--  同上--><union-subclass name="Bird" table="t_bird"><property name="height" /></union-subclass></class></hibernate-mapping>

每个具体类一张表映射,不能采用自增的方式生成主键。原因就是增加一个Pig,然后在增加一个Bird的时候,可能出现重复主键。


总结一下:

每个继承树一张表优点是:查询速度快,效率高;缺点是:存在大量冗余,而且在查询的数据特别大时,不适合采用该种方式。

每个类一张表优点是:层次清楚,无冗余;缺点是:类的层次多,并且有一个类就需要有一个表,导致会产生很多表。而且,查询时关联的表太多,影响查询速度。

每个具体类一张表优点是:层次清楚,无冗余;缺点是:使用自增主键方式会产生重复逐渐。


总之,最好的方式就是根据具体情况,酌情选择。

原创粉丝点击