【HIbernate框架学习】:Hibernate对象继承关系映射(三)

       每个类一张表

       子类和父类,除非将父类定义成抽象的,否则父类也是一张表、

       这种策略是使用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实体类:

[java] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. package com.demo.domain;  
  2.   
  3. public class Animal {  
  4.   
  5.     private int id;  
  6.     private String name;  
  7.     private boolean sex;  
  8.   
  9.     public int getId() {  
  10.         return id;  
  11.     }  
  12.   
  13.     public void setId(int id) {  
  14.         this.id = id;  
  15.     }  
  16.   
  17.     public String getName() {  
  18.         return name;  
  19.     }  
  20.   
  21.     public void setName(String name) {  
  22.         this.name = name;  
  23.     }  
  24.   
  25.     public boolean isSex() {  
  26.         return sex;  
  27.     }  
  28.   
  29.     public void setSex(boolean sex) {  
  30.         this.sex = sex;  
  31.     }  
  32.       
  33. }  

       Pig实现类:

[java] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. package com.demo.domain;  
  2.   
  3. public class Pig extends Animal {  
  4.   
  5.     private int weight;  
  6.   
  7.     public int getWeight() {  
  8.         return weight;  
  9.     }  
  10.   
  11.     public void setWeight(int weight) {  
  12.         this.weight = weight;  
  13.     }  
  14.       
  15. }  

       Bird实体类:

[java] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. package com.demo.domain;  
  2.   
  3. public class Bird extends Animal {  
  4.   
  5.     private int height;  
  6.   
  7.     public int getHeight() {  
  8.         return height;  
  9.     }  
  10.   
  11.     public void setHeight(int height) {  
  12.         this.height = height;  
  13.     }  
  14.       
  15. }  

       对象关系映射文件:

<?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.demo.domain">
	<class name="Animal" table="t_animal" lazy="false">
		<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>

       测试类:

[java] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. package com.demo.test;  
  2.   
  3. import java.util.Iterator;  
  4. import java.util.List;  
  5.   
  6. import org.hibernate.Session;  
  7.   
  8. import com.demo.domain.Animal;  
  9. import com.demo.domain.Bird;  
  10. import com.demo.domain.HibernateUtils;  
  11. import com.demo.domain.Pig;  
  12.   
  13. import junit.framework.TestCase;  
  14.   
  15. public class ExtendsTest extends TestCase {  
  16.   
  17.     public void testSave1() {  
  18.         Session session = null;  
  19.         try {  
  20.             session = HibernateUtils.getSession();  
  21.             session.beginTransaction();  
  22.               
  23.             Pig pig = new Pig();  
  24.             pig.setName("小猪猪");  
  25.             pig.setSex(true);  
  26.             pig.setWeight(200);  
  27.             session.save(pig);  
  28.               
  29.             Bird bird = new Bird();  
  30.             bird.setName("小鸟鸟");  
  31.             bird.setSex(false);  
  32.             bird.setHeight(100);  
  33.             session.save(bird);  
  34.               
  35.             session.getTransaction().commit();  
  36.         }catch(Exception e) {  
  37.             e.printStackTrace();  
  38.             session.getTransaction().rollback();  
  39.         }finally {  
  40.             HibernateUtils.closeSession(session);  
  41.         }  
  42.     }     
  43.       
  44.     /** 
  45.      * 采用load查询,通过Pig查询 
  46.      */  
  47.     public void testLoad1() {  
  48.         Session session = null;  
  49.         try {  
  50.             session = HibernateUtils.getSession();  
  51.             session.beginTransaction();  
  52.               
  53.             Pig pig = (Pig)session.load(Pig.class1);  
  54.             System.out.println(pig.getName());  
  55.               
  56.             session.getTransaction().commit();  
  57.         }catch(Exception e) {  
  58.             e.printStackTrace();  
  59.             session.getTransaction().rollback();  
  60.         }finally {  
  61.             HibernateUtils.closeSession(session);  
  62.         }  
  63.     }     
  64.   
  65.     /** 
  66.      * 采用load查询,通过Animal查询 
  67.      */  
  68.     public void testLoad2() {  
  69.         Session session = null;  
  70.         try {  
  71.             session = HibernateUtils.getSession();  
  72.             session.beginTransaction();  
  73.               
  74.             Animal a = (Animal)session.load(Animal.class1);  
  75.             System.out.println(a.getName());  
  76.               
  77.             session.getTransaction().commit();  
  78.         }catch(Exception e) {  
  79.             e.printStackTrace();  
  80.             session.getTransaction().rollback();  
  81.         }finally {  
  82.             HibernateUtils.closeSession(session);  
  83.         }  
  84.     }     
  85.       
  86.     /** 
  87.      * 采用load查询,通过Animal查询 
  88.      */  
  89.     public void testLoad3() {  
  90.         Session session = null;  
  91.         try {  
  92.             session = HibernateUtils.getSession();  
  93.             session.beginTransaction();  
  94.               
  95.             Animal a = (Animal)session.load(Animal.class1);  
  96.             //因为load默认支持lazy,所以我们看到的是Animal的代理  
  97.             //所以采用instanceof无法鉴别出真正的类型Pig  
  98.             //所load在此情况下是不支持多态查询的  
  99.             //多态查询:hibernate在加载数据的时候,能够采用instancof鉴别出其真正的类型  
  100.             if (a instanceof Pig) {  
  101.                 System.out.println(a.getName());  
  102.             }else {  
  103.                 System.out.println("不是猪!");  
  104.             }  
  105.               
  106.             session.getTransaction().commit();  
  107.         }catch(Exception e) {  
  108.             e.printStackTrace();  
  109.             session.getTransaction().rollback();  
  110.         }finally {  
  111.             HibernateUtils.closeSession(session);  
  112.         }  
  113.     }         
  114.       
  115.     /** 
  116.      * 采用load查询,通过Animal查询 
  117.      * 将<class>标签中的lazy设置为false 
  118.      */  
  119.     public void testLoad4() {  
  120.         Session session = null;  
  121.         try {  
  122.             session = HibernateUtils.getSession();  
  123.             session.beginTransaction();  
  124.               
  125.             Animal a = (Animal)session.load(Animal.class1);  
  126.             //可以正确判断出其真正的类型  
  127.             //因为映射文件中lazy设置为false,返回的不再是代理类而是真正的类型  
  128.             //所以可以鉴别出来  
  129.             //此种情况下load是支持多态查询的  
  130.             if (a instanceof Pig) {  
  131.                 System.out.println(a.getName());  
  132.             }else {  
  133.                 System.out.println("不是猪!");  
  134.             }  
  135.               
  136.             session.getTransaction().commit();  
  137.         }catch(Exception e) {  
  138.             e.printStackTrace();  
  139.             session.getTransaction().rollback();  
  140.         }finally {  
  141.             HibernateUtils.closeSession(session);  
  142.         }  
  143.     }         
  144.       
  145.     /** 
  146.      * 采用get查询,通过Animal查询 
  147.      */  
  148.     public void testLoad5() {  
  149.         Session session = null;  
  150.         try {  
  151.             session = HibernateUtils.getSession();  
  152.             session.beginTransaction();  
  153.               
  154.             Animal a = (Animal)session.get(Animal.class1);  
  155.             //可以鉴别出其真正的类型,因为get返回的就是具体类  
  156.             //get是支持多态查询的  
  157.             if (a instanceof Pig) {  
  158.                 System.out.println(a.getName());  
  159.             }else {  
  160.                 System.out.println("不是猪!");  
  161.             }  
  162.               
  163.             session.getTransaction().commit();  
  164.         }catch(Exception e) {  
  165.             e.printStackTrace();  
  166.             session.getTransaction().rollback();  
  167.         }finally {  
  168.             HibernateUtils.closeSession(session);  
  169.         }  
  170.     }     
  171.       
  172.     /** 
  173.      * 采用hql查询Animal 
  174.      */  
  175.     @SuppressWarnings("unchecked")  
  176.     public void testLoad6() {  
  177.         Session session = null;  
  178.         try {  
  179.             session = HibernateUtils.getSession();  
  180.             session.beginTransaction();  
  181.               
  182.             List<Animal> animalList = session.createQuery("from Animal").list();  
  183.             for (Iterator<Animal> iter=animalList.iterator(); iter.hasNext();) {  
  184.                 Animal a = (Animal)iter.next();  
  185.                 //采用hql查询返回的是真正的类型,所以hql支持多态查询  
  186.                 if (a instanceof Pig) {  
  187.                     System.out.println(a.getName());  
  188.                 }else if (a instanceof Bird) {  
  189.                     System.out.println(a.getName());  
  190.                 }  
  191.             }  
  192.               
  193.             session.getTransaction().commit();  
  194.         }catch(Exception e) {  
  195.             e.printStackTrace();  
  196.             session.getTransaction().rollback();  
  197.         }finally {  
  198.             HibernateUtils.closeSession(session);  
  199.         }  
  200.     }     
  201.       
  202.     /** 
  203.      * 采用hql查询Animal 
  204.      */  
  205.     @SuppressWarnings("rawtypes")  
  206.     public void testLoad7() {  
  207.         Session session = null;  
  208.         try {  
  209.             session = HibernateUtils.getSession();  
  210.             session.beginTransaction();  
  211.               
  212.             List list = session.createQuery("from java.lang.Object").list();  
  213.             for (Iterator iter=list.iterator(); iter.hasNext();) {  
  214.                 Object o = iter.next();  
  215.                 if (o instanceof Pig) {  
  216.                     System.out.println(o);  
  217.                 }else if (o instanceof Bird) {  
  218.                     System.out.println(o);  
  219.                 }  
  220.             }  
  221.               
  222.             session.getTransaction().commit();  
  223.         }catch(Exception e) {  
  224.             e.printStackTrace();  
  225.             session.getTransaction().rollback();  
  226.         }finally {  
  227.             HibernateUtils.closeSession(session);  
  228.         }  
  229.     }         
  230. }  

       testSave1()方法:

       控制台输出:

       

       数据库显示:

       

       testLoad1()方法:

       控制台输出:

       

       testLoad2()方法:

       控制台输出:

       

       testLoad3()方法:

       控制台输出:

       

       testLoad4()方法:

       控制台输出:

       

       testLoad5()方法:

       控制台输出:

       

       testLoad6()方法:

       控制台输出:

       

       testLoad7()方法:

       控制台输出:

       

        以上三种策略,各有优缺点:
        单表继承:查询速度最快,效率高,但是存在冗余字段
        具体表继承:层次最明了,这是优点,也是缺点,而且数据操作效率不高      

        类表继承:层次清楚,无冗余;但是如果使用自增主键方式会产生重复主键。需要使用手动分配主键。



  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值