一、继承实现的三种策略

1.1,单表继承。每棵类继承树使用一个表(table per class hierarchy) ——>本文主要介绍的继承策略

类继承树对应多个类,要把多个类的信息存放在一张表中,必须有某种机制来区分哪些记录是属于哪个类的。这种机制就是,在表中添加一个字段,用这个字段的值来进行区分。用hibernate实现这种策略的时候,有如下步骤:

1,父类用普通的<class>标签定义,在父类中定义一个discriminator,即指定这个区分的字段的名称和类型

如:<discriminator column=”XXX” type=”string”/>

2,子类使用<subclass>标签定义,在定义subclass的时候,需要注意如下几点:Subclass标签的name属性是子类的全路径名;在Subclass标签中,用discriminator-value属性来标明本子类的discriminator字段(用来区分不同类的字段)的值;Subclass标签,既可以被class标签所包含(这种包含关系正是表明了类之间的继承关系),也可以与class标签平行。 当subclass标签的定义与class标签平行的时候,需要在subclass标签中,添加extends属性,里面的值是父类的全路径名称。子类的其它属性,像普通类一样,定义在subclass标签的内部。

PS:唯一字段隔离,也就是所谓的type,通过type确定子类的类型,每条数据中包含了需要的所有信息字段

1.2,每个具体类一个表(table per concrete class)(有一些限制)

这种策略使用joined-subclass标签来定义子类。父类、子类,每个类都对应一张数据库表。在父类对应的数据库表中,实际上会存储所有的记录,包括父类和子类的记录;在子类对应的数据库表中,这个表只定义了子类中所特有的属性映射的字段。子类与父类,通过相同的主键值来关联。实现这种策略的时候,有如下步骤:

1,父类用普通的<class>标签定义即可,父类不再需要定义discriminator字段

2,子类用<joined-subclass>标签定义,在定义joined-subclass的时候,需要注意如下几点:Joined-subclass标签的name属性是子类的全路径名;Joined-subclass标签需要包含一个key标签,这个标签指定了子类和父类之间是通过哪个字段来关联的。如:<key column=”PARENT_KEY_ID”/>,这里的column,实际上就是父类的主键对应的映射字段名称。

3,Joined-subclass标签,既可以被class标签所包含(这种包含关系正是表明了类之间的继承关系),也可以与class标签平行。 当Joined-subclass标签的定义与class标签平行的时候,需要在Joined-subclass标签中,添加extends属性,里面的值是父类的全路径名称。子类的其它属性,像普通类一样,定义在joined-subclass标签的内部。

PS:表隔离,每个表中都只有属于自身对应的属性,如果要获取完整的数据,则需要通过外键联合查询

1.3,具体表继承。每个子类一个表(table per subclass)

这种策略使用union-subclass标签来定义子类。每个子类对应一张表,而且这个表的信息是完备的,即包含了所有从父类继承下来的属性映射的字段(这就是它跟joined-subclass的不同之处,joined-subclass定义的子类的表,只包含子类特有属性映射的字段)。实现这种策略的时候,有如下步骤:

1,父类用普通<class>标签定义即可

2,子类用<union-subclass>标签定义,在定义union-subclass的时候,需要注意如下几点:Union-subclass标签不再需要包含key标签(与joined-subclass不同);Union-subclass标签,既可以被class标签所包含(这种包含关系正是表明了类之间的继承关系),也可以与class标签平行。 当Union-subclass标签的定义与class标签平行的时候,需要在Union-subclass标签中,添加extends属性,里面的值是父类的全路径名称。子类的其它属性,像普通类一样,定义在Union-subclass标签的内部。这个时候,虽然在union-subclass里面定义的只有子类的属性,但是因为它继承了父类,所以,不需要定义其它的属性,在映射到数据库表的时候,依然包含了父类的所有属性的映射字段。

PS:表隔离,与每个具体类不同的是,这种策略只会为每个具体的子类生成表单,而在每个表单里,既包含了父类的属性,又包含了自身的属性。当需要查询一条完整数据的时候,不需要联合外键!

二、实例介绍继承映射

2.1,建立实体类和映射

Animal类:

<span style="font-family:KaiTi_GB2312;font-size:18px;">package com.angel.hibernate;

public class Animal {

	private int id;

	private String name;

	private boolean sex;

	public int getId() {
return id;
} public void setId(int id) {
this.id = id;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public boolean isSex() {
return sex;
} public void setSex(boolean sex) {
this.sex = sex;
}
}
</span>

Bird类:

<span style="font-family:KaiTi_GB2312;font-size:18px;">package com.angel.hibernate;

public class Bird extends Animal {

	private int height;

	public int getHeight() {
return height;
} public void setHeight(int height) {
this.height = height;
}
}
</span>

Pig类:

<span style="font-family:KaiTi_GB2312;font-size:18px;">package com.angel.hibernate;

public class Pig extends Animal {

	private int weight;

	public int getWeight() {
return weight;
} public void setWeight(int weight) {
this.weight = weight;
}
}
</span>

映射文件:

<span style="font-family:KaiTi_GB2312;font-size:18px;"><?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>
<class name="com.angel.hibernate.Animal" table="t_animal" lazy="false">
<id name="id">
<generator class="native" />
</id>
<!-- 加入鉴别标签,且必须放在id后面 -->
<discriminator column="type" type="string"/>
<property name="name" />
<property name="sex" type="boolean" /> <subclass name="com.angel.hibernate.Pig" discriminator-value="P">
<property name="weight" />
</subclass>
<subclass name="com.angel.hibernate.Bird" discriminator-value="B">
<property name="height" />
</subclass>
</class> </hibernate-mapping> </span>

2.2,测试类

<span style="font-family:KaiTi_GB2312;font-size:18px;">package com.angel.hibernate;

import org.hibernate.Session;

import junit.framework.TestCase;

public class test_extend extends TestCase {

	public void testSave() {
Session session = null;
try {
// 创建session对象
session = HibernateUtils.getSession();
// 开启事务
session.beginTransaction(); Pig pig = new Pig();
pig.setName("daddy pig");
pig.setSex(true);
pig.setWeight(200);
session.save(pig); Bird bird = new Bird();
bird.setName("mummy bird");
bird.setSex(true);
bird.setHeight(100);
session.save(bird); session.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
session.getTransaction().rollback();
} finally {
HibernateUtils.closeSession(session);
}
} public void testLoad(){
Session session=null;
try {
session = HibernateUtils.getSession();
session.beginTransaction();
Animal a = (Animal)session.load(Animal.class, 1);
//load默认支持lazy,所以我们看到的是Animal的代理,采用instanceof无法鉴别出真正的类型Pig
//如果想要load支持多态查询,则需要将lazy值设置为false
if (a instanceof Pig) {
System.out.println(a.getName());
}else {
System.out.println("不是猪!");
}
session.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
session.getTransaction().rollback();
}finally {
HibernateUtils.closeSession(session);
}
} }
</span>

三、多态查询

多态查询:hibernate在加载数据的时候,能够采用instancof鉴别出其真正的类型

在Hibernate中,支持多台查询的有:get、Hql。而对于load,因为其默认支持延迟加载lazy,所以它不支持多态查询,返回的只是一个代理值。如果想要让load支持多态查询,则需要在配置文件中将其lazy属性设置为false。

四、总结

继承映射在实际运用中还是很广泛中,在做这个例子的时候,突然想起来多租户数据隔离的三个策略,其实跟这个差不多。额,说明我脑袋里还是装东西了嘛。然后对于继承映射的三种策略,可以看出的是,单表继承是比较简单而且效率高的,只需要维护一个表。而具体表策略则需要进行外键维护等,相对来说单表继承是一个比较好的选择!

【Hibernate 5】继承映射配置及多态查询的更多相关文章

  1. 【JavaEE】Hibernate继承映射,不用多态查询只查父表的方法

    几个月前,我在博问里面发了一个问题:http://q.cnblogs.com/q/64900/,但是一直没有找到好的答案,关闭问题以后才自己解决了,在这里分享一下. 首先我重复一下场景,博问里面举的动 ...

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

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

  3. Hibernate之继承映射

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

  4. 初识Hibernate之继承映射

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

  5. Hibernate框架 主配置文件 Hibernate.cfg.xml 映射配置 说明

    1 主配置文件 Hibernate.cfg.xml 主配置文件中主要配置:数据库连接信息.其他参数.映射信息! 常用配置查看源码: hibernate-distribution-3.6.0.Final ...

  6. Hibernate的继承映射

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

  7. hibernate中继承映射保存

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

  8. 继承映射关系 subclass的查询

    Person大类的映射文件配置 1 <hibernate-mapping package="com.zh.hibernate.subclass"> <class ...

  9. Hibernate一对一关联映射配置

    一.一对一关联 Hibernate提供了两种映射一对一关联关系的方式:按照外键映射和按照主键映射.下面以员工账号和员工档案表为例,介绍这两种映射方式,并使用这两种映射方式分别完成以下持久化操作: (1 ...

随机推荐

  1. (WF)InvalidWorkflowException

    之前一直运行正常的xaml突然不能运行了,总是显示如下错误. The test caught an unhandled exception. Caught: System.Activities.Inv ...

  2. BestCoder HDU 5750 Dertouzos

    Dertouzos 题意: 有中文,不说. 题解: 我看了别人的题解,还有个地方没懂, 为什么是 if(d%prime[i]==0) break; ? 代码: #include <bits/st ...

  3. cf 605B B. Lazy Student 构造 好题

    题意: 一个n个节点的图,有m条边,已知这个图的一个mst 现在如果我们知道这个图的m条边,和知道mst的n-1条边是哪些,问能不能构造出一个满足条件的图 思路:排序+构造 数组deg[i]表示节点i ...

  4. [物理学与PDEs]第3章 磁流体力学

    [物理学与PDEs]第3章第1节 等离子体 [物理学与PDEs]第3章第2节 磁流体力学方程组 2.1 考虑到导电媒质 (等离子体) 的运动对 Maxwell 方程组的修正 [物理学与PDEs]第3章 ...

  5. 程序员的sql金典

    1.数据库基础概念 2.数据类型 3.通过SQL语句管理数据表 4.数据的增删改 5.Select的基本用法 6.高级数据过滤 7.数据分组 8.限制结果集行数和抑制重复数据 9.计算字段 10.不从 ...

  6. sublime相关设置

    1.设置Sublime Text新标签页打开文件 "open_files_in_new_window": false,

  7. qt上用opencv显示摄像头视频

    参考:http://blog.csdn.net/augusdi/article/details/8865541 代码如下: 注意,要在ui界面上放置一个“Vertical Layout”控件,调整到合 ...

  8. filter的执行顺序

    一直没有仔细去研究下filter ,最近系统的测试了下: 先看代码吧 FirstFilter.java ================== package com.test.filter; impo ...

  9. Java多线程之Wait()和Notify()

    1.Wait()和Notify.NotifyAll都是Object的方法 2.多线程的协作是通过控制同一个对象的Wait()和Notify()完成 3.当调用Wait()方法时,当前线程进入阻塞状态, ...

  10. Eclipse Tomcat配置/管理/调试指南

    从myeclipse转到Eclipse最不方便的之一莫过于Web项目部署了,老是在想怎么不能把myeclipse的那个移植过来,或者有没有高人能按照Myeclipse开发一个,非常遗憾. 原版的Ecl ...