前面的两篇文章中,我们介绍了两张表之间的各种相互关联映射关系,但往往我们也会遇到两张表甚至多张表之间共有着多个相同的字段。例如:

如图,student表和teacher表共同具有id,name,age等字段,而我们的继承映射就是这样的一个思想,抽象出这些共有的字段为一张父表,让子表对其进行继承,这样就可以大大降低我们实体类代码的冗余性,增强其结构的完善。

Hibernate支持以下三种数据表的生成策略:

  • 每个类分层结构一张表
  • 每个子类一张表
  • 每个具体类一张表

一、每个类分层结构一张表

     对于这种数据表的生成策略,最终Hibernate会在数据库中生成一张数据表,这张数据表的结构会是如下的:

无论你是student记录还是teacher记录,都会被存储到这张集成的新表中。下面是实现代码:

public class Person {
private int id;
private String name;
//省略get,set方法
}
public class Student extends Person {
private int grade;
//省略get,set方法
}
public class Teacher extends Person {
private int salary;
//省略get,set方法
}

下面是映射配置文件的书写:

<class name="Person" abstract="true" table="newTable">
<id name="id">
<generator class="assigned"/>
</id>
<!--指定鉴别器列的名称和类型-->
<discriminator column="type" type="java.lang.String"/>
<property name="name"/>
<!--指定集成到新表的子实体类-->
<subclass name="Student" discriminator-value="stu">
<!--配置继承类中其他属性-->
<property name="grade"/>
</subclass>
<subclass name="Teacher" discriminator-value="tea">
<property name="salary"/>
</subclass>
</class>

abstract="true"指定Hibernate不用将Person表生成具体表,只需要生成一张集成的新表即可。table="newTable"则指定了新表的表名,鉴别器就是用来区分当前记录时student或是teacher的一个标记,它会在新表中生成一个字段,而该字段的名称和类型都在此处进行指定。

subclass标签用于配置需要集成到新表中子实体类的一些属性等内容。下面我们通过插入操作了解这种映射策略对具体数据库的实际操作。

Student student = new Student();
student.setId(1);
student.setName("stu1");
student.setGrade(100); Teacher teacher = new Teacher();
teacher.setId(2);
teacher.setName("tea1");
teacher.setSalary(10000); session.save(student);
session.save(teacher);

将两条不同类型的记录保存到数据库中,

newTable是一张综合的表,主要由student表和teacher表集成而来,对应于student表的记录salary字段的值为空,对应于teacher表记录的grade字段值为空。那在我们取数据的时候,Hibernate该如何区分当前记录对应的是哪个实体类的呢?

Person person = (Person)session.get(Person.class,1);
if(person instanceof Student){
Student student1 = (Student)person;
System.out.println("i am student,my grade is:"+student1.getGrade());
}

实际上,Hibernate使用多态来对数据记录进行接收,无论你是Student记录或teacher记录,都可以被person类型接收。使用这种策略方式映射数据表只会生成一张表,但是很大的一个问题是,当很多张表进行集成的时候会导致表结构复杂混乱。

二、每个具体类映射成一张表

     这种数据表的生成策略会为每个实体类生成一张数据表,就上述例子而言,会为person,student,teacher都生成一张表。首先我们看映射配置文件:

<class name="Person">
<id name="id">
<generator class="assigned"/>
</id>
<property name="name"/>
<union-subclass name="Student" table="students">
<property name="grade"/>
</union-subclass>
<union-subclass name="Teacher" table="teachers">
<property name="salary"/>
</union-subclass>
</class>

这里的配置其实不需要多的解释,union-subclass告诉Hibernate当前配置的实体类是person类的子类,并用table属性指定对应数据库的表名。下面我们通过插入数据来看看具体生成的表的结构:

很明显,我们的person表只起到一个模板的效果并没有什么实际的价值,而我们students表和teachers表的id,name字段都是从person表中继承得到的。

三、每个子类一张表

     这种数据表的生成策略的主要思想就是将公共的信息存放在父表中,子表只保存自己独有的字段信息了。例如:

<class name="Person">
<id name="id" column="id">
<generator class="native"/>
</id>
<property name="name"/>
<joined-subclass name="Student" table="students">
<key column="sId" />
<property name="grade"/>
</joined-subclass>
<joined-subclass name="Teacher" table="teachers">
<key column="tId"/>
<property name="salary"/>
</joined-subclass>
</class>

我们使用 joined-subclass来配置继承子类,在Hibernate生成数据表的时候会将student和teacher表的主键作为外键关联父表的主键。下面是插入数据:

Student student = new Student();
student.setName("stu1");
student.setGrade(12); Teacher teacher = new Teacher();
teacher.setName("tea1");
teacher.setSalary(1233); session.save(student);
session.save(teacher);

显然,我们student或者teacher表不再需要存放name或者其他共有字段的信息,只需要通过自己的主键去查找父表即可得到。

至此,有关继承映射的三个策略已经介绍结束,总结不到之处,望指出。

初识Hibernate之继承映射的更多相关文章

  1. hibernate笔记--继承映射关系的三种实现方式

    单表继承映射(一张表): 假设我们现在有三个类,关系如下: Person类有两个子类Student和Teacher,并且子类都具有自己独有的属性.这种实体关系在hibernate中可以使用单表的继承映 ...

  2. Hibernate之继承映射

    1. Hibernate支持三种继承映射策略: –使用 subclass进行映射:将域模型中的每一个实体对象映射到一个独立的表中,也就是说不用在关系数据模型中考虑域模型中的继承关系和多态. –使用 j ...

  3. Hibernate的继承映射

    对象模型示例: 继承映射的实现方式有以下三种: (一)每棵类继承树一张表 (二)每个类一张表 (三)每个子类一张表 (一)每棵类继承树一张表 关系模型如下: 映射文件如下: <hibernate ...

  4. 初识Hibernate之关联映射(二)

    上篇我们介绍了关联映射的几种形式,有单向多对一,单向一对多,还有双向一对多.本篇接着介绍有关关联映射的其他几种映射方式,主要有以下几种: 基于外键的单向一对一关联映射 基于主键的单向一对一关联映射 单 ...

  5. hibernate中继承映射保存

    1 简单继承映射,在子类上进行映射配置,可以将父类属性直接配置在子类映射文件中. 简单例子如下:teacher类继承自Person类. public class Person { private in ...

  6. 初识Hibernate之关联映射(一)

    上篇文章我们对持久化对象进行的学习,了解了它的三种不同的状态并通过它完成对数据库的映射操作.但这都是基于单张表的操作,如果两张或者两张以上的表之间存在某种关联,我们又该如何利用持久化对象进行操作呢?本 ...

  7. hibernate映射-继承映射

    对于面向对象的程序设计语言而言,继承和多态是两个最基本的概念.Hibernate的继承映射可以理解成持久化类之间的继承关系.例如:人和学生之间的关系.学生继承人,可以认为学生是一个特殊的人,如果对人进 ...

  8. Hibernate4.x之映射关系--继承映射

    Hibernate的继承映射可以理解为持久化类之间的继承关系.例如:人和学生之间的关系.学生继承了人,可以认为学生是一个特殊的人,如果对人进行查询,学生的实例也将被得到. Hibernate支持以下三 ...

  9. 【Hibernate框架】三种继承映射

    一.综述 大家都知道,hibernate作为ORM框架的一个具体实现,最大的一个优点就是是我们的开发更加的能体现出"面向对象"的思想.在面向对象开发中,类与类之间是可以相互继承的( ...

随机推荐

  1. javascript this对象

    函数运行时,自动生成的一个内部对象,只能在函数内部使用 随着函数使用场合的不同,this的值也发生着改变,但是有一个总原则:this指的是调用函数的那个对象(核心) this对象的指向 一般情况下,我 ...

  2. 简单的独享smb

    1.是这样的,因为办公区域有一个千兆的交换机,但是我的台式机硬盘有点小,500G的,就把一个旧的台式网卡换成了千兆的,装了个CentOS6.5,最小化的,装了个samba,就开始用了: 2.由于是自己 ...

  3. 201521123028 《java程序设计》 第7周学习总结

    1. 本周学习总结 2. 书面作业 Q1.ArrayList代码分析 1.1 解释ArrayList的contains源代码 Ans: ArrayList的contains源代码 contain源代码 ...

  4. 201521123115 《Java程序设计》第3周学习总结

    Java 第三周总结 1.本周学习总结 {{uploading-image-747934.png(uploading...)}} 2.书面作业 1.代码阅读 public class Test1 { ...

  5. 201521123088《java程序设计》第三周学习总结

    1. 本周学习总结 本周学习了关于Java的封装,所谓封装就是将属性私有化,提供公有的方法访问私有属性 2. 书面作业 代码阅读 public class Test1 { private int i ...

  6. 【干货】教你如何利用fullPage.js以及move.js插件打造高端大气的网站效果!

    前言: 如今我们经常能见到全屏网站,尤其是国外网站.这些网站用几幅很大的图片或色块做背景,再添加一些简单的内容,显得格外的高端大气上档次. 在学习过jQuery插件之后,才发现之前的很多网站特效完全可 ...

  7. iScroll在谷歌浏览器中的问题

    通常情况下,我们会使用iScroll.js做移动端的下拉刷新和上拉加载功能,当然,还有很多其他功能. 不过,在使用iScroll的时候,在谷歌浏览器中出现不支持的情况,即,做移动的时候,出现卡顿或是每 ...

  8. 数据库Mysql的安装及操作---数据引擎

    一.1.什么是数据           描述事物的符号记录称为数据.       2.什么是数据库         存放数据的仓库,只不过这个仓库在计算机上存储设备上. 二.Mysql的介绍     ...

  9. [07] ServletContext上下文对象

    1.上下文的概念 我们在说到Servlet的继承关系时,提到自定义Servlet实际上间接实现了Servlet和ServletConfig两个接口,其中ServletConfig接口中定义了一个方法叫 ...

  10. MySQL 经典面试题

    MySQL 面试 1 存储过程 什么是存储过程 存储过程是一些编译好的SQL语句 因为系统在调用SQL的时候比较浪费时间,所以之前先将一些基本的额SQL语句代码进行编译(对单表或多表的增删改查),然后 ...