【SSH系列】Hibernate映射 -- 继承映射

分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow

也欢迎大家转载本篇文章。分享知识,造福人民,实现我们中华民族伟大复兴!

               

 开篇前言

 在前面的博文中,小编介绍了hibernate中的映射,一对一,一对多,多对多,单向,双向等,今天这篇博文,小编主要来介绍一下hibernate中的继承映射,小伙伴都知道在C#中,如果想要实现继承,直接在子类中添加冒号即可继承父类,在java中可以用关键字extends实现,那么在hibernate中,什么是继承映射呢?继承映射的方式又是什么?继承映射具有几种策略呢?不同策略之间又存在着怎么样的区别和联系呢?该博文,小编就来简单的总结一下hibernate中的继承映射。

 继承映射是什么

 首先,我们来看这样的一张表结构:

          

 上述的表结构就是继承映射的一种,小猪猪和小鸟鸟他们共用了字段Name和Sex,除此之外,有些字段是针对某种数据而存在的,所以在数据库中为空,如上所,weight是针对小猪猪而言的,而height是针对小鸟鸟而言的,从上面的表结构,我们可以得出,有些字段是共用的,有些字段是自己独有的,她们通过type这个字段来进行区别,ok,小编相信,小伙伴们现在对继承映射已经有了一定的了解,接着小编来介绍继承映射的方式。   

  继承映射方式

 在前面的博文中,小编提到过,c#和java中的继承,但是在数据库的世界中,表之间是没有任何关键字可以明确指明这两张表的父子关系,表与表是没有继承关系这样的说法的。为了将程序领域中的继承关系反映到数据中,Hibernate为我们提供了三种策略,分别是:
 a、每颗类继承树一张表;
 b、每个类一张表;
 c、每个具体类一张表;
 我们依然从uml入手,看对象模型,如下所示:
 
 Pig和Bird都继承Animal,她们都有id,name,sex,但是Pig主要看weight,而Bird主要看height,此时如果把这些数据存入到数据库中,可以有三种方案,也就是三种策略。ok,接下来结合Animal这个例子,分别对三种策略进行讲解。
 第一种、每颗类继承树一张表
 这种方式,只生成一个table,对应的继承映射策略是“单表继承”。如图:   

 

 每颗类继承树一张表,也就是使用一张表表示所有继承体系下的类的属性的并集,这种策略是使用<subclass>标签来实现的。因为类继承体系下会有许多个子类,要把多个类的信息存放在一张表中,必须有某种机制来区分哪些记录是属于哪个类的。Hibernate中的这种机制就是,在表中添加一个字段,用这个字段的值来进行区分。在表中添加这个标示列使用<discriminator>标签来实现,hbm.xml文件如下所示:

<?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.bjpowernode.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>
 第二种、每个类一张表

 这种方式,每个类生成一个table,对应的继承策略是“类表继承”。如图:
 

 这种策略是使用<joined-subclass>标签来定义子类的。父类、子类都对应一张数据库表。在父类对应的数据库表中,它存储了所有记录的公共信息,实际上该父类对应的表会包含所有的记录,包括父类和子类的记录;在子类对应的数据库表中,这个表只定义了子类中所特有的属性映射的字段。子类对应的数据表与父类对应的数据表,通过一对一主键关联的方式关联起来。Hbm.xml文件如下所示:

<?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.bjpowernode.hibernate">   <class name="Animal" table="t_animal">  <id name="id">   <generator class="native"/>  </id>  <property name="name"/>  <properties 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 = "bird"/>   <property name="height"/>  </joined-subclass>  </class>      </hibernate-mapping>
 第三种、每个具体类一张表
 这种方式,生成三张表,对应的策略是“具体表继承”,如下图所示:

 
 每一个子类对应的数据库表都包含了父类的信息,并且包含了自己独有的属性。每个子类对应一张表,而且这个表的信息是完备的,即包含了所有从父类继承下来的属性映射的字段。这种策略是使用<union-subclass>标签来定义子类的。代码如下所示:

<?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.bjpowernode.hibernate"> <class name="Animal" table="t_animal" abstract="true">  <id name="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>
 三种策略对比
     

猜你喜欢

转载自blog.csdn.net/gfjjggg/article/details/84143593