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

继承映射

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

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

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. Emit

    http://www.cnblogs.com/zhuweisky/archive/2008/09/20/1294666.html http://www.cnblogs.com/xiaoxiangfei ...

  2. Java多线程(四) 线程池

    一个优秀的软件不会随意的创建.销毁线程,因为创建和销毁线程需要耗费大量的CPU时间以及需要和内存做出大量的交互.因此JDK5提出了使用线程池,让程序员把更多的精力放在业务逻辑上面,弱化对线程的开闭管理 ...

  3. SSH连接时出现Host key verification failed的原因及解决方法

    SSH连接的时候Host key verification failed. [root@cache001 swftools-0.9.0]# ssh 192.168.1.90@@@@@@@@@@@@@@ ...

  4. 新贵HTML5,2016的发展方向会怎样?

    2014年下半年,微信捧火了HTML5小游戏,自此国内各行各业开始对HTML5保持高涨关注.2015年是国内HTML5行业迅速发展的一年,在媒体大肆渲染“互联网寒冬”之际,HTML5作品的生产数量和传 ...

  5. Building microservices with Spring Cloud and Netflix OSS, part 2

    In Part 1 we used core components in Spring Cloud and Netflix OSS, i.e. Eureka, Ribbon and Zuul, to ...

  6. memcache的一致性hash算法

    <?php /** * 一致性哈希memcache分布式,采用的是虚拟节点的方式解决分布均匀性问题,查找节点采用二分法快速查找 * the last known user to change t ...

  7. Demo学习: Closable Tabs

    Closable Tabs 给tab页添加关闭按钮,设置UniTabSheet.Closable = True这样在tab页的右上角就会出现关闭图标,点击可以关闭当前tab页面: 1. 直接关闭,完成 ...

  8. grunt项目配置

    安装完CLI,还要在项目安装Grunt npm install -g grunt-cli npm install grunt --save-dev 源码放在src下 package.json放在根目录 ...

  9. 【dapper】.net平台下的框架

    http://www.cnblogs.com/yipu/archive/2012/11/21/2780199.html Method Duration Remarks Hand coded (usin ...

  10. 【学习总结】OS X , IOS , IOS SDK , XCode之间的关系

    几个基本的概念 : OS X : 属于桌面PC级别(IMac,MacPro等)对应安装的操作系统 IOS : 属于移动设备级别(Iphone,Ipad等)对应安装的操作系统 XCode: 是一个IDE ...