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(事务))
本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...
随机推荐
- 关于EsayUI中datagrid重复提交后台查询数据的问题
直接上代码: <table id="XXXX" style="width:100%;height:100%;" class="easyui-da ...
- python字典学习笔记
字典是一种可变容器模型,且可存储任意类型对象.键是不可变类型(且是唯一的),值可以是任意类型(不可变类型:整型,字符串,元组:可变类型:列表,字典).字典是无序的,没有顺序关系,访问字典中的键值是通过 ...
- SpringAop源码情操陶冶-AspectJAwareAdvisorAutoProxyCreator
本文将对SpringAop中如何为AspectJ切面类创建自动代理的过程作下简单的分析,阅读本文前需要对AOP的Spring相关解析有所了解,具体可见Spring源码情操陶冶-AOP之ConfigBe ...
- 数据库Oracle
一. 表空间和数据文件的关系: 文件组成:数据文件,控制文件,数据库日志文件 数据文件:.dbf 包含全部数据库数据(表,索引等),一个数据文件仅与一个数据库关联.一旦建立,只增不减. 表空间(Tab ...
- php图片上传服务器
原理是把图片上传到服务器的某个目录,然后在把他的名字存入数据库,或者不需要数据库这部分也行.读取的时候直接读取名字. HTML提交表格 <form method="post" ...
- 开发中关于Git那些事
如果你想精通Git,直接到 Git官网 把这本ProGit掌握已足以Pro Git 此文主要介绍一切开发中常用的git命令和一些配置技巧(诸如git别名配置,log打印技巧,版本回退以及分支管理等). ...
- GoldenGate 传统抽取进程随 DataGuard 主备快速切换的方案(ADG 模式)
环境描述: 1.节点描述 节点 IP 节点描述 11.6.76.221 GG 抽取端 / DG 节点,数据库版本号为 Oracle-11.2.0.3,与 11.6.76.222 组成 DataGuar ...
- 闲聊select和input常用的小插件
前言 在pc端的项目中,经常会用到表单标签,莫过于是select和input这两种,这两种相当常用.但往往原生的功能不尽人意,即使 input中type有n多属性,甚至连时间控件都有,但仍旧满足不了我 ...
- 巧用ecshop做淘宝客
一.第一步 下载文件,可以在http://www.ecshop.com/下载ecshop各个版本的安装包,安装好ECSHOP,然后通过PTF工具下载2个文件到本地进行修改.这个2个文件分别是goods ...
- bash, sh, dash 傻傻分不清楚
原文链接,转载请注明出处: http://www.happycxz.com/m/?p=137 常见shell类型 Bourne shell (sh) UNIX 最初使用,且在每种 UNIX 上都可以使 ...