hibernate学习笔记第14讲-继承映射

 

继承映射:

1,一个类继承树映射到一张表。一般采用第一种。效率高,资源占用率低。


hibernate学习笔记第14讲-继承映射
 1、理解如何映射

           因为类继承树肯定是对应多个类,要把多个类的信息存放在一张表中,必须有某种机制来区分哪些记录是属于哪个类的。

这种机制就是,在表中添加一个字段,用这个字段的值来进行区分。用hibernate实现这种策略的时候,有如下步骤:

父类用普通的<class>标签定义

在父类中定义一个discriminator,即指定这个区分的字段的名称和类型

如:<discriminator column=XXX type=string/>

子类使用<subclass>标签定义,在定义subclass的时候,需要注意如下几点:

Subclass标签的name属性是子类的全路径名

Subclass标签中,用discriminator-value属性来标明本子类的discriminator字段(用来区分不同类的字段)       的值Subclass标签,既可以被class标签所包含(这种包含关系正是表明了类之间的继承关系),也可以与class标签平行。 subclass标签的定义与class标签平行的时候,需要在subclass标签中,添加extends属性,里面的值是父类的全路径名称。子类的其它属性,像普通类一样,定义在subclass标签的内部。

2、理解如何存储

存储的时候hibernate会自动将鉴别字段值插入到数据库中,在加载数据的时候,hibernate能根据这个鉴别值  正确的加载对象

多态查询:在hibernate加载数据的时候能鉴别出正真的类型(instanceOf

 

get支持多态查询

load只有在lazy=false,才支持多态查询

hql支持多态查询   

映射关系:

<hibernate-mapping package="com.bjsxt.hibernate">

<class name="Animal" table="t_animal" lazy="false">

           <id name="id">

                    <generator class="native"/>

           </id>

//鉴别器,必须放在id后面          

<discriminator column="type" type="string"/>

           <property name="name"/>

           <property name="sex"/>

//鉴别值:discriminator-value

           <subclass name="Pig" discriminator-value="P">

                    <property name="weight"/>

           </subclass>

           <subclass name="Bird" discriminator-value="B">

                    <property name="height"/>

           </subclass>

</class>

</hibernate-mapping>

加载:

/**

 * 采用load,通过Pig查询

 */

session.beginTransaction();

                    Pig pig = (Pig)session.load(Pig.class, 1);

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

                    session.getTransaction().commit();

/**

 * 采用load,通过Animal查询

 */

         session.beginTransaction();

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

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

                    session.getTransaction().commit();

/**

 * 采用load,通过Animal查询,不支持多态查询

多态查询:在hibernate加载数据时,能鉴别出真正的类型(instanceof

 */

session.beginTransaction();

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

                    //因为load默认只是lazy,因为我们看到的是Animal的代理对象

                    //所以通过instanceof是反应不出正真的对象类型的

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

                    if (animal instanceof Pig) {

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

                    }else {

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

                    }

                    session.getTransaction().commit();

/**

 * 采用load,通过Animal查询,<class>标签上的lazy=falseload失效后支持多态查询

 */

session.beginTransaction();

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

         //可以正确的判断出Pig的类型,因为lazy=false,返回的是具体的Pig类型

           //此时load支持多态查询

                    if (animal instanceof Pig) {

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

                    }else {

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

                    }

                    session.getTransaction().commit();

/**

 * 采用get,通过Animal查询,能够支持多态查询

 */

session.beginTransaction();

                    //可以正确的判断出Pig的类型,因为返回的是具体的Pig类型

                    //get支持多态查询

                    Animal animal = (Animal)session.get(Animal.class, 1);

                    if (animal instanceof Pig) {

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

                    }else {

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

                    }

                    session.getTransaction().commit();

         /**

 * 查询所有实体对象,因为支持多态查询

 */

session.beginTransaction();

                    List list = session.createQuery("from java.lang.Object").list();

                    for (Iterator iter=list.iterator(); iter.hasNext();) {

                             Object o = iter.next();

                             if (o instanceof Pig) {

                                       System.out.println("Pig");

                             }else if (o instanceof Bird) {

                                       System.out.println("bird");

                             }

                    }

                    session.getTransaction().commit();

2,每个子类映射到一张表。在加载、存储的性能上比第一种低。


hibernate学习笔记第14讲-继承映射
 映射关系:

<hibernate-mapping package="com.bjsxt.hibernate">

      <class name="Animal" table="t_animal">

               <id name="id">

                         <generator class="native"/>

               </id>

               <property name="name"/>

               <property name="sex"/>

               <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,每个具体类映射到一张表。


hibernate学习笔记第14讲-继承映射
 <hibernate-mapping package="com.bjsxt.hibernate">

// abstract="true"抽象,不会生成表

<class name="Animal" abstract="true">

           <id name="id">

//不能使用native,自增,因为pigbird两个表中的id不能相同

                    <generator class="assigned"/>

           </id>

           <property name="name"/>

           <property name="sex"/>

           <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>

 

 

你可能感兴趣的:(java,Hibernate,jdbc,领域模型)