之所以把这两种映射放到一起说,是因为二者都是以复用为目的,减少了代码和配置量,这是相同点;二者之间的不同点类似继承和实现的区别:继承的类是一个事物的抽象,而实现的接口仅仅是功能的抽象。

继承映射

如上面所说,以下面类图为例:

它的映射方式有三种,它们的类和属性相同,只是映射文件不同,当然也导致映射的数据结构也不同,先一下以上三个类,再根据映射文件的不同说明每种映射方式。

Animal

public class Animal {
private int id;
private String name;
private boolean sex;
//省略getter和setter……
}

Bird

public class Bird extends Animal {
private int height;
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
}

Pig

public class Pig extends Animal {
private int weight;
public int getWeight() {
return weight;
}
public void setWeight(int weight) {
this.weight = weight;
}
}

冗余

先来看一下表结构。

很明显,这种方式是将Pig和Bird冗余到一张表,以类型字段区分开来,来看一下它的映射文件:

<hibernate-mapping >
<class name="com.tgb.hibernate.Animal" table="t_animal" >
<id name="id">
<generator class="native" />
</id>
<discriminator column="type" type="string" />
<property name="name" />
<property name="sex" />
<subclass name="com.tgb.hibernate.Pig" discriminator-value="P" >
<property name="weight" />
</subclass>
<subclass name="com.tgb.hibernate.Bird" discriminator-value="B">
<property name="height" />
</subclass>
</class> </hibernate-mapping>

不出所料,这种方式是将两个类以子类的方式嵌入到Animal中,形成一个大“类”,从而映射出一张表,从而将将父、子类的实例全部保存在同一张表内。需要注意的是,Discriminator必须要在subclass之前声明,这个容易理解:先制定规则,再分子类。

联合

同样,先来看一下库表结构。

再来看一下映射文件:

<hibernate-mapping package="com.tgb.hibernate">
<class name="com.tgb.hibernate.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>

如配置文件所示,这种方式是子类联合:子类实例的数据仅保存在子类表中,没有在父类表中有记录。当class标签中没有abstract="true"这个属性时,它也是三张表,当添加此属性后,会生成上述的表结构。

需要注意的是,主键生成策略不能是identity,也不能是native,因为native会根据数据库选择identity或sequence方式,这是因为两个子类表中的主键不能相同,而identity则会导致这个结果。

连接

同样,来看一下表结构。

再来看一下映射文件:

<hibernate-mapping package="com.tgb.hibernate">
<class name="com.tgb.hibernate.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>

可以看到,这种方式是连接的形式,与上一种方式不同的是将子类的属性和父类的属性分开存储,和上面一种方式类似的是,因为都有父类表的外键,子表中的主键也不能重复。

这种存储方式容易出现的问题是,如果继承树的深度很深,那么查询一个子类实例时,因为子类的数据依次保存在其多个父类中,需要跨越多个表,大大影响效率。

这三种存储方式各有优劣,要根据实际情况具体分析使用。

组件映射

以以下类图为例:

Contact类在此的作用就是组件类,需要时引用即可。来看一下简写的类:

Contact

public class Contact {

		private String email;
private String address;
private String zipcode;
private String contactTel;
//省略getter和setter……
}

Employee

public class Employee {

		private int id;
private String name;
private Contact employeeContact;
//省略getter和setter
}

User

public class User {

	private int id;
private String name;
private Contact userContact;
//省略getter和setter……
}

再来看一下组件映射的表结构:

但从表结构上来看,和上面的“联合子类”的继承映射类似。再来看一下User的映射文件(Employee类似):

<hibernate-mapping>
<class name="com.tgb.hibernate.User" table="t_User">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<component name="userContact">
<property name="email"/>
<property name="address"/>
<property name="zipcode"/>
<property name="contactTel"/>
</component>
</class>
</hibernate-mapping>

可以看到Contact此处仅仅是作为组件使用,它仅仅是一个值,而非实体,所以不用Contact的映射文件。它与继承类似,都是为了复用;相比继承映射而言,不同点在于它将功能抽象出来,它的粒度更细,提供了更广的复用范围,与接口类似。

总结

到此为止大致给大家介绍了一下继承映射和组件映射,希望通过对比的方式,将二者的区别和类似展现出来,下篇博客会介绍一下复合主键映射和集合映射。

Hibernate征途(五)之继承映射和组件映射的更多相关文章

  1. .Hibernate一对一映射与组件映射

    1.按照外键映射(Hibernate提供了两种映射一对一关联关系的方式:按照外键映射和按照主键映射) 实现需要: 创建实体类Users1和Resume1 public class Users1 { p ...

  2. 一口一口吃掉Hibernate(五)——一对多单向关联映射

    版权声明:本文为博主原创文章,未经博主允许不得转载.如需转载请声明:[转自 http://blog.csdn.net/xiaoxian8023 ] 在上一篇博客<一口一口吃掉Hibernate( ...

  3. Hibernate(五)——经典解析一对一关联映射

    前面两篇介绍了多对一.一对多的映射.今天分享下一对一的关联映射关系.有两种策略可以实现一对一的关联映射:主键关联.唯一外键关联. 主键关联——两个表有完全相同的主键值,来表示它们的一对一的关系.数据库 ...

  4. Hibernate征途(七)之复合主键映射和集合映射

    把这两种映射放到一起说,是因为这两种映射不像前面的复用型映射.数量和方向型映射那么分类鲜明,所以放到了这个“其他”里面. 复合主键映射 在关系模型中,复合主键和其他的主键方式没有很大区别,但是反映到对 ...

  5. Hibernate组件映射

    Hibernate联合主键映射以及组件映射 在Hibernate中联合主键的形成有两种可能:一种是由多对多映射形成的,多对多映射会形成第三张表,一般来说第三张表的主键是由其他两张表的主键构成的(比如学 ...

  6. java之hibernate之组件映射

    1.在开发中,有的类信息比较复杂,而且某几个信息可以组成某一个部分,这个时候可以采用组件映射,组件映射是一张表映射到多个类.表结构 2.类的设计 Link.java public class Link ...

  7. Hibernate第九篇【组件映射、继承映射】

    前言 到目前位置,我们已经学习了一对一.一对多.多对一.多对多映射了-既然Hibernate是ORM实现的框架,它还提供了组件映射和继承映射..本博文主要讲解组件映射和继承映射 Java主要的类主要有 ...

  8. hibernate学习四(关系映射一对一与组件映射)

    一.关系映射简介 在数据库中,表与表的关系,仅有外键.但使用hibernate后,为面向对象的编程,对象与对象的关系多样化:如 一对一,一对多,多对多,并具有单向和双向之分. 开始练习前,复制上一次项 ...

  9. hibernate(七)组件映射与多对一映射

    一.组件映射 用注解配置组件映射: Husband为我们映射的类,wife是这个类的一部分(属性不能与husband中属性重名,不要写Entity注解,不要有主键) Husband类:(在getWif ...

随机推荐

  1. SQL Server中批量替换数据

    SQL Server数据库中批量替换数据的方法 SQL Server数据库操作中,我们可能会根据某写需要去批量替换数据,那么如何批量修改替换数据呢?本文我们就介绍这一部分内容,接下来就让我们一起来了解 ...

  2. 一段画对角线的canvas代码,之前没有写过canvas代码,现在记录下来

    <canvas id="other" style="width:320px;height:320px;"></canvas> var o ...

  3. php array_walk 和 array_reduce函数

    1.array_walk:将数组中的元素(键+值)依次取出传给处理的函数,函数处理完就完了,没有返回值. $arr1=array( 'name'=>'zhangsan', 'age'=>3 ...

  4. 提升PHP性能的21种方法

    提升PHP性能的21种方法. 1.用单引号来包含字符串要比双引号来包含字符串更快一些.因为PHP会在双引号包围的字符串中搜寻变量,单引号则不会.2.如果能将类的方法定义成static,就尽量定义成st ...

  5. 在centos 6.4下安装opencv 2.3.1

    系统环境介绍: centos 6.4 1.安装依赖包 yum install cmake gcc gcc-c++ gtk+-devel gimp-devel gimp-devel-tools gimp ...

  6. Beaglebone Back学习一(开发板介绍)

    随着开源软件的盛行.成熟,开源硬件也迎来了春天,先有Arduino,后有Raspherry Pi,到当前的Beaglebone .相信在不久的将来,开源项目将越来越多,越来越走向成熟.         ...

  7. iOS中为网站添加图标到主屏幕以及增加启动画面

    虽然没有能力开发Native App,但还是可以利用iOS中Safari浏览器的特性小小的折腾一下,做一个伪Web App满足下小小的虚荣心的. 既然是在iOS中的Safari折腾的,那么代码中利用到 ...

  8. 导入 Mysql 示例数据库 employees

    Mysql也有跟Oracle的scott与employees相似的数据库,这样就免除了每次都要自己建表并插入数据了. Mysql提供的供练习使用的数据库employees,下面地址:https://l ...

  9. 十一、mysql输入安全

    .尽量使用“绑定参数”功能,php中可用pdo进行一系列操作 .php可使用mysql_real_escape_string()函数进行输入过滤:

  10. easy ui 下拉框绑定数据select控件

    easy ui 中的下拉框控件叫做select,具体代码如下: html代码:①.这是一个公司等级的下拉框 <tr> <td>公司等级:</td> <td&g ...