Hibernate笔记——表的的4种继承关系
原文:http://justsee.iteye.com/blog/1070588
=====================================
一、继承关系_整个继承树映射到一张表
对象模型(Java类结构)

一个类继承体系一张表(subclass)(表结构)

Employee.java
- package com.taobao.hibernate.domain;
- public class Employee {
- private int id;
- private String name;
- private Department department;
- 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 Department getDepartment() {
- return department;
- }
- public void setDepartment(Department department) {
- this.department = department;
- }
- }
Skiller.java
- package com.taobao.hibernate.domain;
- public class Skiller extends Employee {
- private String skill;
- public String getSkill() {
- return skill;
- }
- public void setSkill(String skill) {
- this.skill = skill;
- }
- }
Sales.java
- package com.taobao.hibernate.domain;
- public class Sales extends Employee {
- private String sell;
- public String getSell() {
- return sell;
- }
- public void setSell(String sell) {
- this.sell = sell;
- }
- }<span style="white-space: normal;">
- </span>
这里我们考虑设计数据库是把员工都涉及在一张表,那么如何区分员工种类呢?加入员工类型这个字段来区别。
只需更改Employee.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 package="domain">
- <class name="Employee" discriminator-value="0">
- <id name="id">
- <generator class="native"/>
- </id>
- <discriminator column="type" type="int"></discriminator>
- <property name="name"></property>
- <many-to-one name="dpt" column="dpt_id" lazy="false"></many-to-one>
- <subclass name="Skiller" discriminator-value="1">
- <property name="skill" ></property>
- </subclass>
- <subclass name="Sales" discriminator-value="2">
- <property name="sell"></property>
- </subclass>
- </class>
- </hibernate-mapping>
<discriminator column="type" type="int"/>中的type默认值是string。
所有子类定义的字段不能为空。
使用了<discriminator column="type" type="int"></discriminator>这个标签,就是映射了type字段,然后Hibernate会根据type字段的值来确定从数据库中取过来的是什么对象。
在查询的get方法时,也可以自动识别,会自动用相对应的对象去封装数据。
一个继承树映射到一张表的话,会有很多空字段,不符合关系数据库的设计模式。
二、继承关系_每个类映射到一张表

这时候Employee.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 package="domain">
- <class name="Employee">
- <id name="id">
- <generator class="native"/>
- </id>
- <property name="name"></property>
- <many-to-one name="dpt" column="dpt_id" lazy="false"></many-to-one>
- <joined-subclass name="Skiller">
- <key column="employee_id"></key>
- <property name="skill"></property>
- </joined-subclass>
- <joined-subclass name="Sales">
- <key column="employee_id"></key>
- <property name="sell"></property>
- </joined-subclass>
- </class>
- </hibernate-mapping>
<joined-subclass name="Sales">
子类对应类名为Sales,表名为Sales
<key column="employee_id"></key>
通过employee_id与Employee表关联
<property name="sell"></property>
设置sell属性
</joined-subclass>
这样就完成了Hibernate的配置,生成的表符合上面所说的表结构。
Hibernate: insert into Department (name) values (?)
插入部门
Hibernate: insert into Employee (name, dpt_id) values (?, ?)
插入销售员工到员工表
Hibernate: insert into Sales (sell, employee_id) values (?, ?)
插入销售员工到销售员工表
Hibernate: insert into Employee (name, dpt_id) values (?, ?)
插入技术员工到员工表
Hibernate: insert into Skiller (skill, employee_id) values (?, ?)
插入技术员工到技术员工表
5条插入信息
现在又有问题了,既然用到了多表关联,那么删除这些级联操作会怎么样呢
Hibernate: delete from Sales where employee_id=?
Hibernate: delete from Employee where id=?
发现两条delete语句很好的将员工信息删除掉了。
这里还需要注意的是,查询的时候避免使用多态查询,多表连接查询效率较低,最好明确指定查询的类别,不要直接用员工类进行查询。
三、继承关系_鉴别器与内连接相结合
把属性不多的类对应的列放到父类列中,把子类属性多的单独用一个表。这里假设Sales有很多列

内容和上两篇没有什么大的区别,原理类似,只是标签上略有不同。
Employee.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 package="domain">
- <class name="Employee" discriminator-value="0">
- <id name="id">
- <generator class="native"/>
- </id>
- <discriminator column="type" type="int"/>
- <property name="name"></property>
- <many-to-one name="dpt" column="dpt_id" lazy="false"></many-to-one>
- <subclass name="Skiller" discriminator-value="1">
- <property name="skill"></property> </subclass>
- <subclass name="Sales" <strong><span style="color: #ff0000;">discriminator-value="2"</span></strong>>
- <join table="sales">
- <key column="employee_id"></key>
- <property name="sell"></property>
- </join>
- </joined-subclass>
- </class>
- </hibernate-mapping>
四、继承关系_每.类映射一张独立表

可见表之间都是独立的,没有关联的。
Employee.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 package="domain">
- <class name="Employee">
- <id name="id">
- <generator class="hilo"/>
- </id>
- <property name="name"></property>
- <many-to-one name="dpt" column="dpt_id" lazy="false"></many-to-one>
- <union-subclass name="Skiller">
- <property name="skill"></property>
- </union-subclass>
- <union-subclass name="Sales">
- <property name="sell"></property>
- </union-subclass>
- </class>
- </hibernate-mapping>
这种方式的局限在于,如果一个属性在超类中做了映射,其字段名必须与所有子类表中定义的相同(Hibernate可能在后续版本中放宽此限制)。除此之外,使用union-subclass映射策略是不可使用identity的主键生成策略,因为同一类继承层次中所有实体类都需要使用同一个主键种子(即多个持续化实体对应的记录的主键是连续的)。受此影响,也不应该使用native主键生成策略,因为native会根据数据库来选择使用identity或sequence策略。,所以不要native,identity,sequence主键生成策略,可以是increment,hilo。
如果父类是abstract=”true”就不会有表与之对应。
隐式多态,映射文件没有联系,限制比较多很少使用。
Hibernate笔记——表的的4种继承关系的更多相关文章
- C++中的三种继承关系
C++中的三种继承关系 先看类中声明成员时的三种访问权限 public : 可以被任意实体访问 protected : 只允许子类及本类的成员函数访问 private : 只允许本类的成员函数访问 在 ...
- Hibernate之jpa实体映射的三种继承关系
在JPA中,实体继承关系的映射策略共有三种:单表继承策略(table per class).Joined策略(table per subclass)和Table_PER_Class策略. 1.单表继承 ...
- <读书笔记>Javascript系列之6种继承(面向对象)
写在前面: 以下三选一: 阅读博文JavaScript 对象详解. 阅读<JavaScript权威指南>第6章. 阅读<JavaScript高级程序设计>第6章. 注意:只需要 ...
- Hibernate中的Entity类之间的继承关系之一MappedSuperclass
在hibernate中,Entity类可以继承Entity类或非Entity类.但是,关系数据库表之间不存在继承的关系.那么在Entity类之间的继承关系,在数据库表中如何表示呢? Hibernate ...
- Hibernate逍遥游记-第10章 映射继承关系-003继承关系树中的每个类对应一个表(joined-subclass)
1. 2. <?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate ...
- Hibernate逍遥游记-第10章 映射继承关系-002继承关系树中的根类对应一个表(discriminator、subclass)
1. 2. <?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate ...
- Hibernate逍遥游记-第10章 映射继承关系-001继承关系树中的每个具体类对应一个表
1. 2. <?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate ...
- hibernate笔记--继承映射关系的三种实现方式
单表继承映射(一张表): 假设我们现在有三个类,关系如下: Person类有两个子类Student和Teacher,并且子类都具有自己独有的属性.这种实体关系在hibernate中可以使用单表的继承映 ...
- C++中的类继承(1) 三种继承方式
继承是使代码可以复用的重要手段,也是面向对象程序设计的核心思想之一.简单的说,继承是指一个对象直接使用另一对象的属性和方法.继承呈现了 面向对象程序设 计的层次结构, 体现了 由简单到复杂的认知过程. ...
随机推荐
- 在使用SQLite插入数据时出现乱码的解决办法
在VC++中通过sqlite3.dll接口对sqlite数据库进行操作,包括打开数据库,插入,查询数据库等,如果操作接口输入参数包含中文字符,会导致操作异常.例如调用sqlite3_open打开数 ...
- MATLAB 利用filter函数实现滑动平均滤波
function [ y ] = moving_average( x, win_size ) y1=filter(ones(1,win_size/2+1)/win_size,1,x); y2=fi ...
- online training
https://www.skillfeed.com/browse http://teamtreehouse.com/features http://www.pluralsight.com/ https ...
- C# 微信公众号
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.We ...
- codeforces D. Queue 找规律+递推
题目链接: http://codeforces.com/problemset/problem/353/D?mobile=true H. Queue time limit per test 1 seco ...
- Promises与Javascript异步编程
Promises与Javascript异步编程 转载:http://www.zawaliang.com/2013/08/399.html 在如今都追求用户体验的时代,Ajax应用真的是无所不在.加上这 ...
- JS 学习笔记--6---日期和时间
在日期和时间这一块的学习中发现,其实和其他大部分的高级语言中时间和日期的操作差不多,没什么特别的,但是要注意的就是 ECMAScript中规定的一些方法在各大浏览器中的实现方式是不一样的,也就是说存在 ...
- poj 3009 Curling 2.0
题目来源:http://poj.org/problem?id=3009 一道深搜题目,与一般搜索不同的是,目标得一直往一个方向走,直到出界或者遇到阻碍才换方向. 1 #include<iostr ...
- iOS开发之runtime的运用-获取当前网络状态
之前写过runtime的一些东西,这次通过runtime获取一些苹果官方不想让你拿到的东西,比如,状态栏内部的控件属性.本文将通过runtime带你一步步拿到状态栏中显示网络状态的控件,然后通过监测该 ...
- JAVA算法系列 快速排序
java算法系列之排序 手写快排 首先说一下什么是快排,比冒泡效率要高,快排的基本思路是首先找到一个基准元素,比如数组中最左边的那个位置,作为基准元素key,之后在最左边和最右边设立两个哨兵,i 和 ...