Hibernate学习(七)---【继承映射--每棵继承树映射成一张表】

Hibernate学习(七)---【继承映射--每棵继承树映射成一张表】

 每棵继承树映射成一张表

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支持多态查询 

package  com.bjsxt.hibernate;

public   class  Animal {
    
    
private   int  id;
    
    
private  String name;
    
    
private   boolean  sex;

    
public   int  getId() {
        
return  id;
    }

    
public   void  setId( int  id) {
        
this .id  =  id;
    }

    
public  String getName() {
        
return  name;
    }

    
public   void  setName(String name) {
        
this .name  =  name;
    }

    
public   boolean  isSex() {
        
return  sex;
    }

    
public   void  setSex( boolean  sex) {
        
this .sex  =  sex;
    }
}

 

package  com.bjsxt.hibernate;

public   class  Bird  extends  Animal {

    
private   int  height;

    
public   int  getHeight() {
        
return  height;
    }

    
public   void  setHeight( int  height) {
        
this .height  =  height;
    }
}

 

package  com.bjsxt.hibernate;

public   class  Pig  extends  Animal {
    
    
private   int  weight;

    
public   int  getWeight() {
        
return  weight;
    }

    
public   void  setWeight( int  weight) {
        
this .weight  =  weight;
    }
}

 

<? 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.bjsxt.hibernate" >
    
< class  name ="Animal"  table ="t_animal"  lazy ="false" >
        
< id  name ="id" >
            
< generator  class ="native" />
        
</ id >
        
< discriminator  column ="type"  type ="string" />
        
< property  name ="name" />
        
< property  name ="sex" />
        
< subclass  name ="Pig"  discriminator-value ="P" >
            
< property  name ="weight" />
        
</ subclass >
        
< subclass  name ="Bird"  discriminator-value ="B" >
            
< property  name ="height" />
        
</ subclass >
    
</ class >
</ hibernate-mapping >

package  com.bjsxt.hibernate;

import  java.util.Iterator;
import  java.util.List;

import  org.hibernate.Session;

import  junit.framework.TestCase;

public   class  ExtendsTest  extends  TestCase {

    
public   void  testSave1() {
        Session session 
=   null ;
        
try  {
            session 
=  HibernateUtils.getSession();
            session.beginTransaction();
            
            Pig pig 
=   new  Pig();
            pig.setName(
" 猪猪 " );
            pig.setSex(
true );
            pig.setWeight(
100 );
            session.save(pig);
            
            Bird bird 
=   new  Bird();
            bird.setName(
" 鸟鸟 " );
            bird.setSex(
false );
            bird.setHeight(
50 );
            session.save(bird);
            
            session.getTransaction().commit();
        }
catch (Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        }
finally  {
            HibernateUtils.closeSession(session);
        }
    }    
    
    
/**
     * 采用load,通过Pig查询
     
*/
    
public   void  testLoad1() {
        Session session 
=   null ;
        
try  {
            session 
=  HibernateUtils.getSession();
            session.beginTransaction();
            
            Pig pig 
=  (Pig)session.load(Pig. class 1 );
            System.out.println(pig.getName());
            
            session.getTransaction().commit();
        }
catch (Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        }
finally  {
            HibernateUtils.closeSession(session);
        }
    }
    
    
/**
     * 采用load,通过Animal查询
     
*/
    
public   void  testLoad2() {
        Session session 
=   null ;
        
try  {
            session 
=  HibernateUtils.getSession();
            session.beginTransaction();
            
            Animal animal 
=  (Animal)session.load(Animal. class 1 );
            System.out.println(animal.getName());
            
            session.getTransaction().commit();
        }
catch (Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        }
finally  {
            HibernateUtils.closeSession(session);
        }
    }            
    
    
/**
     * 采用load,通过Animal查询
     
*/
    
public   void  testLoad3() {
        Session session 
=   null ;
        
try  {
            session 
=  HibernateUtils.getSession();
            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();
        }
catch (Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        }
finally  {
            HibernateUtils.closeSession(session);
        }
    }            
    
    
/**
     * 采用load,通过Animal查询,将<class>标签上的lazy=false
     
*/
    
public   void  testLoad4() {
        Session session 
=   null ;
        
try  {
            session 
=  HibernateUtils.getSession();
            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();
        }
catch (Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        }
finally  {
            HibernateUtils.closeSession(session);
        }
    }        
    
    
/**
     * 采用get,通过Animal查询
     
*/
    
public   void  testLoad5() {
        Session session 
=   null ;
        
try  {
            session 
=  HibernateUtils.getSession();
            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();
        }
catch (Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        }
finally  {
            HibernateUtils.closeSession(session);
        }
    }    
    
    
/**
     * 采用get,通过Animal查询
     
*/
    
public   void  testLoad6() {
        Session session 
=   null ;
        
try  {
            session 
=  HibernateUtils.getSession();
            session.beginTransaction();
//             List animalList = session.createQuery("from Animal").list();
//             for (Iterator iter = animalList.iterator(); iter.hasNext();) {
//                 Animal a = (Animal)iter.next();
//                  // 能够正确的鉴别出正真的类型,hql是支持多态查询的
//                 if (a instanceof Pig) {
//                     System.out.println("是Pig");
//                 }else if (a instanceof Bird) {
//                     System.out.println("是bird");
//                 } 
//             }
            
            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();
        }
catch (Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        }
finally  {
            HibernateUtils.closeSession(session);
        }
    }    
    
}

你可能感兴趣的:(Hibernate学习(七)---【继承映射--每棵继承树映射成一张表】)