Hibernate映射详解(六)--继承映射

        在对象中,是有继承的概念的。那既然Hibernate实现表采用的是一种面向对象的方式,则当然也少不了继承的概念。举个例子来说,小猪和小鸟都是动物,他们都有一些共同的属性。如他们都有一个id,有姓名,有性别。但是呢,小猪有重量,小鸟游高度。(just举例哈)。这就是一个继承关系了,在Hibernate中我们怎么实现它呢?先把这个情况用图来表示一下

实现后表的形式为:

         这三种方式所生成的表格想必大家不难理解。那hibernate中具体是怎么实现的呢?

         这三种方式的实体类构造完全是一样的。实现形式如下

public class Pigextends Animal {

    privateintweight;

}

public class Birdextends Animal {

    privateintheight;

}

     public class Animal {

          privateintid;

          private Stringname;

          privatebooleansex;

}

        关联映射的映射文件都是与实体相对应的,每个实体对应一个映射文件。继承映射就省去了这些麻烦。他们只需要一个映射文件就搞定了。我们看一下不同方式的继承映射文件是如何实现的。要注意,继承映射中映射文件的名称为Extends.hbm.xml

每个类一张表

<hibernate-mappingpackage="com.bjpowernode.hibernate">                                      

    <classname="Animal"table="t_animal">

        <idname="id">

            <generatorclass="native"/>

        </id>

        <propertyname="name"/>

        <propertyname="sex"/>

        <joined-subclassname="Pig"table="t_pig">

           <keycolumn="pid"/>

           <propertyname="weight"/>

       </joined-subclass>

       <joined-subclassname="Bird"table="t_bird">

           <keycolumn="bid"/>

           <propertyname="height"/>

       </joined-subclass>

    </class>

</hibernate-mapping>

每个具体类一张表(要注意一下,在保存

对象的时候id不能重复,所以此处主键不

能采用自动添加的形式,要手动添加)

<hibernate-mappingpackage="com.bjpowernode.hibernate">

    <classname="Animal"table="t_animal"abstract="true">

        <idname="id">

            <generatorclass="assigned"/>

        </id>

        <propertyname="name"/>

        <propertyname="sex"/>

        <union-subclassname="Pig"table="t_pig">

           <propertyname="weight"/>

       </union-subclass>

       <union-subclassname="Bird"table="t_bird">

           <propertyname="height"/>

       </union-subclass>

    </class>

</hibernate-mapping>

每颗继承树一张表

<hibernate-mappingpackage="com.bjpowernode.hibernate">

    <classname="Animal"table="t_animal"lazy="false">

        <idname="id">

            <generatorclass="native"/>

        </id>

        <discriminatorcolumn="type"type="string"/>

        <propertyname="name"/>

        <propertyname="sex"/>

        <subclassname="Pig"discriminator-value="P">

           <propertyname="weight"/>

       </subclass>

       <subclassname="Bird"discriminator-value="B">

           <propertyname="height"/>

       </subclass>

    </class>

</hibernate-mapping>

        继承映射,对于鉴别值的存储时hibernate自动完成的,不需要我们手动去存储,其他的存储与关联映射没有区别。但是,对于查找来说,他就发挥出他的优势了。多态查找的功能,你不必确切的知道他属于哪个类,只要知道父类就能完成查找功能。gethql方式是完全支持多态查询的,但是load有些特殊。他在lazy设置为false的情况下支持多态查询,当为true时,则不支持。我们看一个例子体会一下多态查询。

例一:

Animal a = (Animal)session.load(Animal.class, 1);

System.out.println(a.getName());

hibernate可以自动鉴别出你是哪个类的实例,取出相应的值

 

 

 

 

 

 

 

 

 

例二:

Animal a = (Animal)session.load(Animal.class, 1);

//因为load默认支持lazy,所以我们看到的是Animal的代理

//所以采用instanceof无法鉴别出真正的类型Pig

//load在此情况下是不支持多态查询的

//多态查询:hibernate在加载数据的时候,能够采用instancof鉴别出其真正的类型

if (ainstanceof Pig) {

    System.out.println(a.getName());

}else {

    System.out.println("不是猪!");

}

通过instanceof可以自动鉴别出具体是哪个对象的实例。

 

             通过instanceof可以自动鉴别出具体是哪个对象的实例。到这里,继承映射就介绍完了。对它的三种实现形式,我采用表格比照的方式,将他们的实现形式以及实现的结果进行了展示。三种方式适合与不同的场景。具体什么时候应用根据他们的实现结果,根据需求我们在判断吧!

posted @ 2012-05-28 08:38  转航  阅读(219)  评论(0编辑  收藏  举报