hibernate映射关系——继承映射

 今天这篇博客,说的是hibernate的继承映射。

一、以前使用过继承映射吗?

      刚听到继承映射的时候,不知道是怎么一回事。视频看完,哦,原来我使用过。没有学习过ORM之类知识的孩子们,如果是第一次听说,不要担心,你们一定使用过,只是不知道它用过这样一个名称而已。看下面的表:

    

    这样的表结构,是不是很熟悉的。这就是继承映射的一种。

    特点:

     1、表中存放了几种不同类型的数据

  2、他们用“Type”字段来区分。

  3、字段有公用的,有特殊的。

           公用的就是:name,sex ,但是有些字段是针对某种数据而存在的,所以数据库中有写字典为“空”。例如:heigth 是针对“小鸟鸟”,而weight 是针对“小猪猪”的。

      继承映射不光只有这一种形式,我们来看看继承映射的形式。



二、继承映射

       什么继承映射?要说继承映射之前,得先说说继承映射的由来。大家知道在面向对象的程序领域中,类与类之间是有继承关系的,例如Java世界中只需要extends关键字就可以确定这两个类的父子关系,但是在关系数据库的世界中,表与表之间没有任何关键字可以明确指明这两张表的父子关系,表与表是没有继承关系这样的说法的。为了将程序领域中的继承关系反映到数据中,Hibernate为我们提供了三种方案,分别是:

   1:一颗继承树一张表

   2:一个类对应一张表

   3:每个具体子类使用一张表。

   我们先看 继承关系类图,这就是一颗继承树。


    

       通过这颗树,来理解这三种表现形式。

       首先是第一种:使用一张表表示所有继承体系下的类的属性的并集

  这种策略是使用<subclass>标签来实现的。因为类继承体系下会有许多个子类,要把多个类的信息存放在一张表中,必须有某种机制来区分哪些记录是属于哪个类的。Hibernate中的这种机制就是,在表中添加一个字段,用这个字段的值来进行区分。在表中添加这个标示列使用<discriminator>标签来实现。这也是第一篇中提到的“例子”。Animal,Pig,Bird都映射到一张表中。

       hbm.xml 如下:      

<!DOCTYPE hibernate-mapping PUBLIC 
	"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
	"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.bjpowernode.hibernate">
	<span style="color:#FF0000;"><class name="Animal</span>" table="t_animal" lazy="false">
		<id name="id">
			<generator class="native"/>
		</id>
		<span style="color:#FF0000;"><discriminator</span> column="type" type="string"/>
		<property name="name"/>
		<property name="sex"/>
		<span style="color:#FF0000;"><subclass</span> name="Pig" discriminator-value="P">
			<property name="weight"/>
		</subclass>
		<span style="color:#FF6666;"><subclass </span>name="Bird" discriminator-value="B">
			<property name="height"/>
		</subclass>
	</class>
</hibernate-mapping>


      其次是第二种:一个类一张表:上图中继承树,就可以被映射成三个表;

      这种策略是使用<joined-subclass>标签来定义子类的。父类、子类都对应一张数据库表。在父类对应的数据库表中,它存储了所有记录的公共信息,实际上该父类对应的表会包含所有的记录,包括父类和子类的记录;在子类对应的数据库表中,这个表只定义了子类中所特有的属性映射的字段。子类对应的数据表与父类对应的数据表,通过一对一主键关联的方式关联起来。

<?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.bjpowernode.hibernate">
    <<span style="color:#FF0000;">class name="Animal"</span> table="t_animal">
        <id name="id">
            <generator class="native"/>
        </id>
        <property name="name"/>
        <property name="sex"/>
        <span style="color:#FF0000;"><joined-subclass</span> name="Pig" table="t_pig">
            <key column="pid"/>
            <property name="weight"/>
        </joined-subclass>
        <span style="color:#FF0000;"><joined-subclass</span> name="Bird" table="t_bird">
            <key column="bid"/>
            <property name="height"/>
        </joined-subclass>
    </class>
</hibernate-mapping>


      最后是每个具体子类一张表:每一个子类对应的数据库表都包含了父类的信息,并且包含了自己独有的属性。每个子类对应一张表,而且这个表的信息是完备的,即包含了所有从父类继承下来的属性映射的字段。这种策略是使用<union-subclass>标签来定义子类的。

<span style="font-family:KaiTi_GB2312;font-size:18px;"><?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.bjpowernode.hibernate">
	<<span style="color:#FF0000;">class name</span>="Animal" table="t_animal" <span style="color:#FF0000;">abstract="true</span>">
		<id name="id">
			<generator class="assigned"/>
		</id>
		<property name="name"/>
		<property name="sex"/>
		<span style="color:#FF0000;"><union-subclass</span> name="Pig" table="t_pig">
			<property name="weight"/>
		</union-subclass>
		<span style="color:#FF0000;"><union-subclass</span> name="Bird" table="t_bird">
			<property name="height"/>
		</union-subclass>
	</class>
</hibernate-mapping></span>


   三种映射形式简单对比

       

      为了方便说明为三种方式按顺序标号为[1][2][3]。
      1、复杂度:           
            [1]简单;
            [2]表较多且之间有外键约束;
         [3]包含重复字段;
      2、查询性能:
            [1]效率高;
            [2]需要表内连接或左外连接;
         [3]若查询父类需查所有子类表;
      3、可维护性:
            [1]只需修改一个表;
            [2]若某个类属性变化只修改这个类对应的表;
         [3]若父类属性变化需要修改所有子类对应的表;
      综上,选择时,可以参考以下原则:
      1、子类属性不是非常多时,优先考虑[1],因为其性能最佳。
      2、子类属性非常多,且对性能要求不是很严格时,优先考虑[2]

  一句话:具体情况具体分析。


  


评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值