Hibernate学习之路-- -映射 继承关系(subclass , joined-subclass,union-subclass )
1.继承映射
举例:对于面向对象的程序设计语言而言,继承和多态是两个最基本的概念。Hibernate 的继承映射可以理解持久化类之间的继承关系。例如:人和学生之间的关系。学生继承了人,可以认为学生是一个特殊的人,如果对人进行查询,学生的实例也将被得到。

1)Hibernate支持三种继承映射策略
① 使用 subclass 进行映射:将域模型中的每一个实体对象映射到一个独立的表中,也就是说不用在关系数据模型中考虑域模型中的继承关系和多态。
② 使用 joined-subclass 进行映射: 对于继承关系中的子类使用同一个表,这就需要在数据库表中增加额外的区分子类类型的字段。
③ 使用 union-subclass 进行映射:域模型中的每个类映射到一个表,通过关系数据模型中的外键来描述表之间的继承关系。这也就相当于按照域模型的结构来建立数据库中的表,并通过外键来建立表之间的继承关系。
2.采用 subclass 元素的继承映射
1)采用 subclass 的继承映射可以实现对于继承关系中父类和子类使用同一张表
2)因为父类和子类的实例全部保存在同一个表中,因此需要在该表内增加一列,使用该列来区分每行记录到低是哪个类的实例----这个列被称为辨别者列(discriminator).
3)在这种映射策略下,使用 subclass 来映射子类,使用 class 或 subclass 的 discriminator-value 属性指定辨别者列的值

1 <hibernate-mapping package="com.jason.hibernate.entities.subclass">
2
3 <class name="Person" table="PERSONS" discriminator-value="Person">
4
5 <id name="id" type="java.lang.Integer">
6 <column name="ID" />
7 <generator class="native" />
8 </id>
9
10 <!-- 配置辨别者列 -->
11 <discriminator column="TYPE" type="string" ></discriminator>
12
13
14 <property name="name" type="java.lang.String">
15 <column name="NAME" />
16 </property>
17
18 <property name="age" type="int">
19 <column name="AGE" />
20 </property>
21
22 <!-- 映射子类Student,使用subclass 进行映射 -->
23 <subclass name="Student" discriminator-value="Student">
24 <property name="school" type="string" column="SCHOOL"></property>
25 </subclass>
26
27 </class>
28 </hibernate-mapping>

4)所有子类定义的字段都不能有非空约束。如果为那些字段添加非空约束,那么父类的实例在那些列其实并没有值,这将引起数据库完整性冲突,导致父类的实例无法保存到数据库中
5)代码

1 package com.jason.hibernate.entities.subclass;
2
3 public class Person {
4
5 private Integer id;
6 private String name;
7 private int age;
8
9 public Integer getId() {
10 return id;
11 }
12
13 public void setId(Integer id) {
14 this.id = id;
15 }
16
17 public String getName() {
18 return name;
19 }
20
21 public void setName(String name) {
22 this.name = name;
23 }
24
25 public int getAge() {
26 return age;
27 }
28
29 public void setAge(int age) {
30 this.age = age;
31 }
32
33 }


1 package com.jason.hibernate.entities.subclass;
2
3 public class Student extends Person {
4
5 private String school;
6
7 public String getSchool() {
8 return school;
9 }
10
11 public void setSchool(String school) {
12 this.school = school;
13 }
14
15
16 }


1 <?xml version="1.0"?>
2 <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
3 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
4
5 <hibernate-mapping package="com.jason.hibernate.entities.subclass">
6
7 <class name="Person" table="PERSONS" discriminator-value="Person">
8
9 <id name="id" type="java.lang.Integer">
10 <column name="ID" />
11 <generator class="native" />
12 </id>
13
14 <!-- 配置辨别者列 -->
15 <discriminator column="TYPE" type="string" ></discriminator>
16
17
18 <property name="name" type="java.lang.String">
19 <column name="NAME" />
20 </property>
21
22 <property name="age" type="int">
23 <column name="AGE" />
24 </property>
25
26 <!-- 映射子类Student,使用subclass 进行映射 -->
27 <subclass name="Student" discriminator-value="Student">
28 <property name="school" type="string" column="SCHOOL"></property>
29 </subclass>
30
31 </class>
32 </hibernate-mapping>


1 package com.jason.hibernate.entities.subclass;
2
3 import java.util.List;
4
5 import org.hibernate.Session;
6 import org.hibernate.SessionFactory;
7 import org.hibernate.Transaction;
8 import org.hibernate.cfg.Configuration;
9 import org.hibernate.service.ServiceRegistry;
10 import org.hibernate.service.ServiceRegistryBuilder;
11 import org.junit.After;
12 import org.junit.Before;
13 import org.junit.Test;
14
15 public class HibernateTest {
16
17 private SessionFactory sessionFactory;
18 private Session session;
19 private Transaction transaction;
20
21
22 // 创建上述三个对象
23 @Before
24 public void init() {
25 Configuration configuration = new Configuration().configure();
26 ServiceRegistry serviceRegistry = new ServiceRegistryBuilder()
27 .applySettings(configuration.getProperties())
28 .buildServiceRegistry();
29
30 sessionFactory = configuration.buildSessionFactory(serviceRegistry);
31
32 session = sessionFactory.openSession();
33
34 transaction = session.beginTransaction();
35 }
36
37 // 关闭上述三个对象
38 @After
39 public void destroy() {
40 transaction.commit();
41 session.close();
42 sessionFactory.close();
43 }
44
45
46 /**
47 * subclass 方法缺点
48 * 1. 使用了辨别者列
49 * 2. 子类独有的字段不能添加非空约束
50 * 3. 若继承层次较深,数据表的字段较多
51 *
52 */
53
54
55 /**
56 *
57 * @Title: testSubClass
58 * @Description: 插入操作
59 *
60 * 1.对于子类对象只需要把记录出入到一张数据表中
61 * 2.辨别者列由hibernate 自动维护
62 */
63
64 @Test
65 public void testSubClass(){
66
67 Person person = new Person();
68 person.setAge(22);
69 person.setName("AA");
70
71 session.save(person);
72
73 Student student = new Student();
74 student.setAge(23);
75 student.setName("BB");
76 student.setSchool("xian");
77
78 session.save(student);
79 }
80
81
82 /**
83 * @Title: testQuery
84 * @Description: 查询
85 * 1.查询父类记录,只需要查询一张表
86 * 2.对于子类记录,只需要查询一张表
87 */
88 @Test
89 public void testQuery(){
90 List<Person> persons = session.createQuery("FROM Person").list();
91 System.out.println(persons.size());
92
93 List<Student> students = session.createQuery("FROM Student").list();
94 System.out.println(students.size());
95 }
96
97
98
99
100
101 }

6)结果

2.采用 joined-subclass 元素的继承映射
1)采用 joined-subclass 元素的继承映射可以实现每个子类一张表
2)采用这种映射策略时,父类实例保存在父类表中,子类实例由父类表和子类表共同存储。因为子类实例也是一个特殊的父类实例,因此必然也包含了父类实例的属性。于是将子类和父类共有的属性保存在父类表中,子类增加的属性,则保存在子类表中。
3)在这种映射策略下,无须使用鉴别者列,但需要为每个子类使用 key 元素映射共有主键。


1 <?xml version="1.0"?>
2 <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
3 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
4
5 <hibernate-mapping package="com.jason.hibernate.entities.joined.subclass">
6
7 <class name="Person" table="PERSONS" discriminator-value="Person">
8
9 <id name="id" type="java.lang.Integer">
10 <column name="ID" />
11 <generator class="native" />
12 </id>
13
14
15 <property name="name" type="java.lang.String">
16 <column name="NAME" />
17 </property>
18
19 <property name="age" type="int">
20 <column name="AGE" />
21 </property>
22
23 <!-- 映射子类Student,使用joined-subclass 进行映射 -->
24 <joined-subclass name="Student" table="STUDENTS">
25 <key column="STUDENT_ID"></key>
26 <property name="school" type="string" column="SCHOOL"></property>
27 </joined-subclass>
28
29
30 </class>
31 </hibernate-mapping>

4)子类增加的属性可以添加非空约束。因为子类的属性和父类的属性没有保存在同一个表中
5)代码
3.采用 union-subclass 元素的继承映射
1)采用 union-subclass 元素可以实现将每一个实体对象映射到一个独立的表中。
1 <union-subclass name="Student" table="STUDENTS">
2 <property name="school" column="SCHOOL" type="string"></property>
3 </union-subclass>
4
2)子类增加的属性可以有非空约束 --- 即父类实例的数据保存在父表中,而子类实例的数据保存在子类表中。
3)子类实例的数据仅保存在子类表中, 而在父类表中没有任何记录
4)在这种映射策略下,子类表的字段会比父类表的映射字段要多,因为子类表的字段等于父类表的字段、加子类增加属性的总和
5)在这种映射策略下,既不需要使用鉴别者列,也无须使用 key 元素来映射共有主键.
6)使用 union-subclass 映射策略是不可使用 identity 的主键生成策略, 因为同一类继承层次中所有实体类都需要使用同一个主键种子, 即多个持久化实体对应的记录的主键应该是连续的. 受此影响, 也不该使用 native 主键生成策略, 因为 native 会根据数据库来选择使用 identity 或 sequence.

7)代码
4.三种方式的性能比较

Hibernate学习之路-- -映射 继承关系(subclass , joined-subclass,union-subclass )的更多相关文章
- [原创]java WEB学习笔记87:Hibernate学习之路-- -映射 继承关系(subclass , joined-subclass,union-subclass )
本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...
- [原创]java WEB学习笔记86:Hibernate学习之路-- -映射 n-n 关系,单向n-n,双向n-n
本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...
- [原创]java WEB学习笔记85:Hibernate学习之路-- -映射 一对一关系 ,基于主键方式实现
本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...
- [原创]java WEB学习笔记84:Hibernate学习之路-- -映射 一对一关系 ,基外键的方式实现
本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...
- Hibernate学习---第八节:继承关系的映射配置
1.单表继承 (1).实体类,代码如下: package learn.hibernate.bean; import java.util.Date; /** * 持久化类设计 * 注意: * 持久化类通 ...
- [原创]java WEB学习笔记82:Hibernate学习之路---映射 一对多关联关系,配置,CRUD方法测试及注意点
本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...
- 【hibernate】映射继承关系
[hibernate]映射继承关系 转载:https://www.cnblogs.com/yangchongxing/p/10405151.html ========================= ...
- [原创]java WEB学习笔记81:Hibernate学习之路--- 对象关系映射文件(.hbm.xml):hibernate-mapping 节点,class节点,id节点(主键生成策略),property节点,在hibernate 中 java类型 与sql类型之间的对应关系,Java 时间和日期类型的映射,Java 大对象类型 的 映射 (了解),映射组成关系
本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...
- [原创]java WEB学习笔记77:Hibernate学习之路---Hibernate 版本 helloword 与 解析,.环境搭建,hibernate.cfg.xml文件及参数说明,持久化类,对象-关系映射文件.hbm.xml,Hibernate API (Configuration 类,SessionFactory 接口,Session 接口,Transaction(事务))
本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...
随机推荐
- 快速部署Telegraf & Influxdb
是什么? Telegraf 是一个用 Go 编写的代理程序,可收集系统和服务的统计数据,并写入到 InfluxDB 数据库.Telegraf 具有内存占用小的特点,通过插件系统开发人员可轻松添加支持其 ...
- 从零使用Python测试。Testing Using Python.
0. 写在前面 本人使用Python测试已有多年,略有些皮毛经验.每次有新员工入职,都会从头教一遍如何入门上手使用Python进行测试.趁这段有空,整理成文档,也好方便后续新员工学习.文章如有不妥之处 ...
- python抽象篇:面向对象
1.面向对象概述 面向过程编程:根据操作数据的函数或语句块来设计程序的. 函数式编程:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可 面向对象编程:数据和功能结合起来,用称为对象的东西包 ...
- WuKong
WuKong Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submis ...
- HDU 4267 A Simple Problem with Integers(树状数组区间更新)
A Simple Problem with Integers Time Limit: 5000/1500 MS (Java/Others) Memory Limit: 32768/32768 K ...
- NTP时间服务器 搭建
1.1 NTP简介 NTP(Network Time Protocol,网络时间协议)是用来使网络中的各个计算机时间同步的一种协议.它的用途是把计算机的时钟同步到世界协调时UTC,其精度在局域网内可达 ...
- ASP.NET Core的身份认证框架IdentityServer4(3)-术语的解释
IdentityServer4 术语 IdentityServer4的规范.文档和对象模型使用了一些你应该了解的术语. 身份认证服务器(IdentityServer) IdentityServer是一 ...
- VS2013装扩展RazorGenerator
问题:vs2013工具扩展和更新搜索关键字:Razor Generator查找不到,如图 解决:下载网址:https://github.com/RazorGenerator/RazorGenerato ...
- HTML5网页音乐播放器
1功能介绍 HTML5中推出了音视频标签,可以让我们不借助其他插件就可以直接播放音视频.下面我们就利用H5的audio标签及其相关属性和方法来制作一个简单的音乐播放器.主要包括以下几个功能: 1.播放 ...
- HTML学习笔记 css定位浮动及瀑布流案例 第十三节 (原创) 参考使用表
#fd { width: 100px; height: 150px; background-color: forestgreen; float: left; } #sd { width: 150px; ...