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(事务))
本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...
随机推荐
- css3+div画大风车
今天已经礼拜三了,周天小颖家的佩佩就要结婚啦,小颖要去当伴娘了,哈哈哈哈哈哈,想想都觉得乐开了花,不过之前她给我说让我当她伴娘时,我说我要减肥,不然她那么瘦弱,我站旁边就感觉像一个圆滚滚的小皮球,小颖 ...
- 关于C#开发中那些编码问题
最近一直在搞各种编码问题,略有心得,与大家分享一番. System.Text提供了Encoding的抽象类,这个类提供字符串编码的方法.常用的编码方式主要有ASCII,Unicode,UTF8(Uni ...
- Matplotlib常用示例入门
一.Matplotlib介绍 Matplotlib 是一个 Python 的 2D绘图库,它以各种硬拷贝格式和跨平台的交互式环境生成出版质量级别的图形.通过 Matplotlib,开发者可以仅需要几行 ...
- ASP.NET Core的身份认证框架IdentityServer4(1)-特性一览
IdentityServer4是ASP.NET Core的一个包含OpenID和OAuth 2.0协议的框架.OpenID和OAuth 的区别请看 https://www.zhihu.com/ques ...
- 蓝桥杯-算法训练--ALGO-4 结点选择
本人是一个刚刚接触C++不久的傻学生~记录一些自己的学习过程.大神路过可以批评指正~ 刚学动态规划,水平还很渣,一下子不知道从何下手,借鉴了一下这位大哥的文章 http://www.cnblogs.c ...
- 拓扑排序 HDU - 5695
众所周知,度度熊喜欢各类体育活动. 今天,它终于当上了梦寐以求的体育课老师.第一次课上,它发现一个有趣的事情.在上课之前,所有同学要排成一列, 假设最开始每个人有一个唯一的ID,从1到NN,在排好队之 ...
- ruby 安装 mysql2 命令
sudo apt-get install libmysql-ruby libmyclient-dev
- 解决mysql启动失败报1067错误
最近做项目使用 mysql 数据库 ,因为卸载了鲁大师造成了数据库文件缺失.重装mysql数据库后启动出现了1067错误,详情如下 在网上查了错误原因,将my.ini文件下的默认搜索引擎换成了 myi ...
- 简单聊聊java中如何判定一个对象可回收
背景 说到java的特性,其中一个最重要的特性便是java通过new在堆中分配给对象的内存,不需要程序员主动去释放,而是由java虚拟机自动的回收.这也是java和C++的主要区别之一:那么虚拟机是如 ...
- Vue Elementui 如何让输入框每次自动聚焦
在项目优化中碰到一个小问题,在每次提示框显示的时候让提示框中的输入框聚焦.如下图.一般情况下提示框是隐藏的.点击了编辑才会弹出. 那么原生属性autofocus 只在模板加载完成时起作用,也就是说只有 ...