随笔-124  评论-49  文章-56  trackbacks-0

继承映射的三种策略:
  * 单表继承,每棵类继承树使用一个表
  * 具体表继承,每个子类一个表
  * 类表继承,每个具体类一个表
-----------------------------------------------------------------
每棵类继承树映射成一张表
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只有在将<class>标签的lazy=false,才支持多态查询
  * hql支持多态查询 

<!--
  Animal:                Bird extends Animal:   Pig extends Animal:
  private int id;         private int height;        private int weight;
  private String name;
-->
  
<class name="Animal" table="t_animal">
        
<id name="id">
            
<generator class="native"/>
        
</id>
        
<discriminator column="type" type="string"/><!--必须在id后面,是检别器  -->
        
<property name="name"/>
        //subclass表示子类,discriminator-value表示检别字段的值
        
<subclass name="Pig" discriminator-value="P">
            
<property name="weight"/>
        
</subclass>
        
<subclass name="Bird" discriminator-value="B">
            
<property name="height"/>
        
</subclass>
    
</class>

public void testSave1(){
        Session session
=null;
        
try{
            session
=HibernateUtils.getSession();
            session.beginTransaction();
            
            Pig pig
=new Pig();
            pig.setName(
"猪八戒");
            pig.setWeight(
100);
            session.save(pig);
            
            Bird bird
=new Bird();
            bird.setName(
"鸟类");
            bird.setHeight(
50);
            session.save(bird);
            
            session.getTransaction().commit();
        }
catch(Exception e){
            e.printStackTrace();
            session.getTransaction().rollback();
        }
finally{
            HibernateUtils.closeSession(session);
        }

    }


    
public void testLoda1(){
        Session session
=null;
        
try{
            session
=HibernateUtils.getSession();
            session.beginTransaction();
            
            Pig p
=(Pig)session.load(Pig.class1);
            System.out.println(p.getName());
            
            session.getTransaction().commit();
        }
catch(Exception e){
            e.printStackTrace();
            session.getTransaction().rollback();
        }
finally{
            HibernateUtils.closeSession(session);
        }

    }

    
    
public void testLoda2(){
        Session session
=null;
        
try{
            session
=HibernateUtils.getSession();
            session.beginTransaction();
            
            Animal a
=(Animal)session.load(Animal.class1);
            System.out.println(a.getName());
            
            session.getTransaction().commit();
        }
catch(Exception e){
            e.printStackTrace();
            session.getTransaction().rollback();
        }
finally{
            HibernateUtils.closeSession(session);
        }

    }

    
    
public void testLoda3(){
        Session session
=null;
        
try{
            session
=HibernateUtils.getSession();
            session.beginTransaction();
            
            Animal a
=(Animal)session.load(Animal.class1);
            
//因为load默认支持lazy,我们看到的是Animal的代理对象
            
//所以通过instanceof是反应不出正真的对象类型的
            
//因些load在默认情况下是不支持多态查询的
            if(a instanceof Pig){
                System.out.println(a.getName());
            }
else{
                System.out.println(
"不是");
            }

            
            session.getTransaction().commit();
        }
catch(Exception e){
            e.printStackTrace();
            session.getTransaction().rollback();
        }
finally{
            HibernateUtils.closeSession(session);
        }

    }

每个子类映射成一张表

1、理解如何映射
  这种策略是使用joined-subclass标签来定义子类的。父类、子类,每个类都对应一张数据库表。
 在父类对应的数据库表中,实际上会存储所有的记录,包括父类和子类的记录;在子类对应的数据库表中,
 这个表只定义了子类中所特有的属性映射的字段。子类与父类,通过相同的主键值来关联。实现这种策略的时候,
 有如下步骤:
 父类用普通的<class>标签定义即可
 父类不再需要定义discriminator字段
 子类用<joined-subclass>标签定义,在定义joined-subclass的时候,需要注意如下几点:
 Joined-subclass标签的name属性是子类的全路径名
 Joined-subclass标签需要包含一个key标签,这个标签指定了子类和父类之间是通过哪个字段来关联的。
 如:<key column=”PARENT_KEY_ID”/>,这里的column,实际上就是父类的主键对应的映射字段名称。
 Joined-subclass标签,既可以被class标签所包含(这种包含关系正是表明了类之间的继承关系),
 也可以与class标签平行。 当Joined-subclass标签的定义与class标签平行的时候,需要在Joined-subclass
 标签中,添加extends属性,里面的值是父类的全路径名称。子类的其它属性,像普通类一样,定义在joined-subclass标签的内部。

<!--
  Animal:                Bird extends Animal:   Pig extends Animal:
  private int id;         private int height;        private int weight;
  private String name;
-->
  
<class name="Animal" table="t_animal2">
        
<id name="id">
            
<generator class="native"/>
        
</id>
        
<property name="name"/>
        
<joined-subclass name="Pig" table="t_pag2">
            
<key column="pagid"/>
            
<property name="weight"/>
        
</joined-subclass>
        
<joined-subclass name="Bird" table="t_bird2">
            
<key column="birdid"/>
            
<property name="height"/>
        
</joined-subclass>
    
</class>

每个具体类映射成一张表

1、理解如何映射
 这种策略是使用union-subclass标签来定义子类的。每个子类对应一张表,而且这个表的信息是完备的,
 即包含了所有从父类继承下来的属性映射的字段(这就是它跟joined-subclass的不同之处,
 joined-subclass定义的子类的表,只包含子类特有属性映射的字段)。实现这种策略的时候,有如下步骤:
 父类用普通<class>标签定义即可
 子类用<union-subclass>标签定义,在定义union-subclass的时候,需要注意如下几点:
 Union-subclass标签不再需要包含key标签(与joined-subclass不同)
 Union-subclass标签,既可以被class标签所包含(这种包含关系正是表明了类之间的继承关系),
 也可以与class标签平行。 当Union-subclass标签的定义与class标签平行的时候,需要在Union-subclass
 标签中,添加extends属性,里面的值是父类的全路径名称。子类的其它属性,像普通类一样,
 定义在Union-subclass标签的内部。这个时候,虽然在union-subclass里面定义的只有子类的属性,
 但是因为它继承了父类,所以,不需要定义其它的属性,在映射到数据库表的时候,依然包含了父类的所
 有属性的映射字段。
 
注意:在保存对象的时候id是不能重复的(不能使用自增生成主键)
   默认父类的animal表会生成,设<class>的abstract="true"就不会生成 

<!--
  Animal:                Bird extends Animal:   Pig extends Animal:
  private int id;         private int height;        private int weight;
  private String name;
-->
  
<class name="Animal" abstract="true">
        
<id name="id">
            
<generator class="assigned"/>
        
</id>
        
<property name="name"/>
        
<union-subclass name="Pig" table="t_pig3">
            
<property name="weight"/>
        
</union-subclass>
        
<union-subclass name="Bird" table="t_bird3">
            
<property name="height"/>
        
</union-subclass>
    
</class>
posted on 2009-11-03 16:15 junly 阅读(167) 评论(0)  编辑  收藏 所属分类: hibernate/orm

只有注册用户登录后才能发表评论。


网站导航: