Hibernate继承映射

  在面向对象的程序领域中,类与类之间是有继承关系的,例如Java世界中只需要extends关键字就可以确定这两个类的父子关系,但是在关系数据库的世界中,表与表之间没有任何关键字可以明确指明这两张表的父子关系,表与表是没有继承关系这样的说法的。为了将程序领域中的继承关系反映到数据中,Hibernate为我们提供了3中方案:

第一种方案:一个子类对应一张表。

第二种方案:使用一张表表示所有继承体系下的类的属性的并集。

第三种方案:每个子类使用一张表只存储它特有的属性,然后与父类所对应的表以一对一主键关联的方式关联起来。

现在假设有People、Student、Teacher三个类,父类为People,Student与Teacher为People的父类,代码如下:

People类:

public class People{/*父类所拥有的属性*/private String id;private String name;private String sex;private String age;private Timestamp birthday;

/*get和set方法*/}

Student类:

public class Student extends People{/*学生独有的属性*/private String cardId;//学号

public String getCardId()    {return cardId;    }

public void setCardId(String cardId)    {this.cardId = cardId;    }}

Teacher类:

public class Teacher extends People{/*Teacher所独有的属性*/private int salary;//工资

public int getSalary()    {return salary;    }

public void setSalary(int salary)    {this.salary = salary;    }}

第一种方案:一个子类对应一张表

该方案是使继承体系中每一个子类都对应数据库中的一张表。示意图如下:

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

配置People.hbm.xml文件:

<?xml version="1.0" encoding="utf-8"?><!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.suxiaolei.hibernate.pojos.People" abstract="true"><id name="id" type="string"><column name="id"></column><generator class="uuid"></generator></id>

<property name="name" column="name" type="string"></property><property name="sex" column="sex" type="string"></property><property name="age" column="age" type="string"></property><property name="birthday" column="birthday" type="timestamp"></property>

<!--         <union-subclass name="com.suxiaolei.hibernate.pojos.Student" table="student">             <property name="cardId" column="cardId" type="string"></property>         </union-subclass>         <union-subclass name="com.suxiaolei.hibernate.pojos.Teacher" table="teacher">             <property name="salary" column="salary" type="integer"></property>         </union-subclass>         --></class><union-subclass name="com.suxiaolei.hibernate.pojos.Student"        table="student" extends="com.suxiaolei.hibernate.pojos.People"><property name="cardId" column="cardId" type="string"></property></union-subclass>

<union-subclass name="com.suxiaolei.hibernate.pojos.Teacher"        table="teacher" extends="com.suxiaolei.hibernate.pojos.People"><property name="salary" column="salary" type="integer"></property></union-subclass></hibernate-mapping>

  以上配置是一个子类一张表方案的配置,<union-subclass>标签是用于指示出该hbm文件所表示的类的子类,如People类有两个子类,就需要两个<union-subclass>标签以此类推。<union-subclass>标签的"name"属性用于指定子类的全限定名称,"table"属性用于指定该子类对应的表的名称,"extends"属性用于指定该子类的父类,注意该属性与<union-subclass>标签的位置有关,若 <union-subclass>标签作为<class>标签的子标签,则"extends"属性可以不设置,否则需要明确设置"extends"属性。<class>标签中的"abstract"属性如果值为true则,不会生成表结构。如果值为false则会生成表结构,但是不会插入数据。

根据People.hbm.xml生成表结构:

   drop table if exists studentdrop table if exists teacher

create table student (        id varchar(255) not null,        name varchar(255),        sex varchar(255),        age varchar(255),        birthday datetime,        cardId varchar(255),primary key (id)    )

create table teacher (        id varchar(255) not null,        name varchar(255),        sex varchar(255),        age varchar(255),        birthday datetime,        salary integer,primary key (id)    )

可以看到一个子类对应一张表。

第二种方案:使用一张表表示所有继承体系下的类的属性的并集

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

该策略的示意图:

将继承体系中的所有类信息表示在同一张表中后,只要是这个类没有的属性会被自动赋上null。

配置People.hbm.xml:

<?xml version="1.0" encoding="utf-8"?><!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.suxiaolei.hibernate.pojos.People" table="people"><id name="id" type="string"><column name="id"></column><generator class="uuid"></generator></id>

<discriminator column="peopleType" type="string"></discriminator>

<property name="name" column="name" type="string"></property><property name="sex" column="sex" type="string"></property><property name="age" column="age" type="string"></property><property name="birthday" column="birthday" type="timestamp"></property>

<subclass name="com.suxiaolei.hibernate.pojos.Student" discriminator-value="student"><property name="cardId" column="cardId" type="string"></property></subclass>

<subclass name="com.suxiaolei.hibernate.pojos.Teacher" discriminator-value="teacher"><property name="salary" column="salary" type="string"></property></subclass></class></hibernate-mapping>

<discriminator>标签用于在表中创建一个标识列,其"column"属性指定标识列的列名,"type"指定了标识列的类型。<subclass>标签用于指定该HBM文件代表类的子类,有多少子类就有多少个该标签,其"name"属性指定子类的名称,"discriminator-value"属性指定该子类的数据的标识列的值是什么,其"extends"属性与<union-subclass>的"extends"属性用法一致。

根据People.hbm.xml生成表结构:

    drop table if exists people

create table people (        id varchar(255) not null,        peopleType varchar(255) not null,        name varchar(255),        sex varchar(255),        age varchar(255),        birthday datetime,        cardId varchar(255),        salary varchar(255),primary key (id)    )

可以看到一张表将继承体系下的所有信息都包含了,其中"peopleType"为标识列。

第三种方案:每个子类使用一张表只存储它特有的属性,然后与父类所对应的表以一对一主键关联的方式关联起来。

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

这种策略的示意图:

  people表中存储了子类的所有记录,但只记录了他们共有的信息,而他们独有的信息存储在他们对应的表中,一条记录要获得其独有的信息,要通过people记录的主键到其对应的子表中查找主键值一样的记录然后取出它独有的信息。

配置People.hbm.xml:

<?xml version="1.0" encoding="utf-8"?><!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.suxiaolei.hibernate.pojos.People" table="people"><id name="id" type="string"><column name="id"></column><generator class="uuid"></generator></id>

<property name="name" column="name" type="string"></property><property name="sex" column="sex" type="string"></property><property name="age" column="age" type="string"></property><property name="birthday" column="birthday" type="timestamp"></property>

<joined-subclass name="com.suxiaolei.hibernate.pojos.Student" table="student"><key column="id"></key><property name="cardId" column="cardId" type="string"></property></joined-subclass>

<joined-subclass name="com.suxiaolei.hibernate.pojos.Teacher" table="teacher"><key column="id"></key><property name="salary" column="salary" type="integer"></property></joined-subclass></class></hibernate-mapping>

<joined-subclass>标签需要包含一个key标签,这个标签指定了子类和父类之间是通过哪个字段来关联的。

根据People.hbm.xml生成表结构:

    drop table if exists peopledrop table if exists studentdrop table if exists teacher

create table people (        id varchar(255) not null,        name varchar(255),        sex varchar(255),        age varchar(255),        birthday datetime,primary key (id)    )

create table student (        id varchar(255) not null,        cardId varchar(255),primary key (id)    )

create table teacher (        id varchar(255) not null,        salary integer,primary key (id)    )

alter table student add index FK8FFE823BF9D436B1 (id), add constraint FK8FFE823BF9D436B1 foreign key (id) references people (id)

alter table teacher add index FKAA31CBE2F9D436B1 (id), add constraint FKAA31CBE2F9D436B1 foreign key (id) references people (id)

可以看到,父类对应的表保存公有信息,子类对应的表保存独有信息,子类和父类对应的表使用一对一主键关联的方式关联起来                                                                                                                                                  转自   Hibernate继承映射

转载于:https://www.cnblogs.com/alex-arne/p/3738220.html

Hibernate继承映射相关推荐

  1. web进修之—Hibernate 继承映射(5)

    先看三个类的继承关系,Payment是父类,CashPayment和CreditCardPayment是Payment的子类: view plaincopy to clipboardprint pub ...

  2. hibernate 继承映射

    在域模型中,类与类之间除了关联关系和聚集关系,还可以存在继承关系,在下图所示的域模型中,Deparment类和Employee类之间为一对多的双向关联关系,Employee类有两个子类:Skiller ...

  3. hibernate继承映射之每个具体类一张表

    数据模型 表person 表student 表worker 对象模型 Person private String id;private String name;private int age;priv ...

  4. hibernate 继承映射(二)

    每个子类映射成一张表: 每个具体类映射成一张表: 本文转自 l363130002 51CTO博客,原文链接:http://blog.51cto.com/liuyj/1693509

  5. Hibernate之继承映射

    Hibernate的继承映射可以理解为两个持久化类之间的继承关系    例如老师和人之间的关系 持久化类  Person类 public  class  Person { private   Inte ...

  6. Hibernate读书笔记---继承映射

    对于面向对象的程序设计语言,继承.多态是两个最基本的概念.Hibernate的继承映射可以理解两个持久化类之间的继承关系. Hibernate支持几种继承映射策略,不管哪种继承映射策略,Hiberna ...

  7. 浅析Hibernate映射(三)——继承映射

    对象模型示例: 继承映射的实现方式有三种: (一)每棵类继承树一张表 关系模型: 映射文件: <hibernate-mapping package="com.jialin.hibern ...

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

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

  9. Hibernate→HQL、query.list()返回数据类型、查询相关语句、分页、原生SQL、@注解、持久化对象状态及生命周期、一多关系、继承映射关系、逆向工程

    HQL Query实例与表 session通用工具类 Query对象 from 类→List<类>接收 映射类 仅查询商品 查询商品及所在商家 别名 返回数据类型定义 Iterator接收 ...

最新文章

  1. 高斯回归过程应用例子
  2. Prewitt 边缘检测
  3. JDK1.8中的HashMap,HashTable,ConcurrentHashMap有什么区别?
  4. JDK13的新特性:AppCDS详解
  5. Servlet使用适配器模式进行增删改查案例(IBaseDaoUtil.java)
  6. Oracle-数据实现竖排打印
  7. 快速根据注释生成接口文档网页工具——Apidoc的使用教程
  8. activex for chrome扩展程序 下载”_Chrome扩展程序一键生成网页骨架屏
  9. php 显示ip所属地 (qq版)
  10. php 位运算 负数,php的位运算详解
  11. RouterOS安装以及搭建DHCP PPPoE PPTP L2TP服务
  12. iphone照片永久删除怎么恢复_微信数据怎么永久删除不被恢复?只删除聊天记录没用,打开这里彻底删除!...
  13. 深入理解java虚拟机---JDK8-废弃永久代(PermGen)迎来元空间(Metaspace)(十二)
  14. (转载)PHP环境搭建-记录
  15. 面试:Synchronized知识点
  16. CF1039E Summer Oenothera Exhibition
  17. java怎么控制数据权限_Java权限控制算法
  18. 【音乐可视化】音乐表演可视化软件分析
  19. 非极大值抑制(Non-max suppression)
  20. 螺丝螺母垫片顺序图片_如何计算螺丝,螺栓和螺母的尺寸

热门文章

  1. android室内地图控件,[开源] Android InDoorView 室内选位控件
  2. java 异常总结_Java异常的十大问题总结
  3. ssm框架重定向_精选 SSM 框架面试题整理
  4. Bootstrap简洁、直观、强悍的前端开发框架
  5. 使用GDAL打开裸数据(RAW)
  6. 转自云风blog:三国志战略版服务器卡顿问题
  7. PowerCMD——cmd的命令行工具
  8. C#将DataTable海量数据导出到Excel
  9. ccf小明放学20分_关于完全平方数的好题(20年3月1日)
  10. SQL 基础笔试题 (三)