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)代码

Person
Student
 Person.hbm.xml 
 HibernateTest

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)代码

Person
Student
 Person.hbm.xml
 HibernateTest

  4.三种方式的性能比较

Hibernate学习之路-- -映射 继承关系(subclass , joined-subclass,union-subclass )的更多相关文章

  1. [原创]java WEB学习笔记87:Hibernate学习之路-- -映射 继承关系(subclass , joined-subclass,union-subclass )

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

  2. [原创]java WEB学习笔记86:Hibernate学习之路-- -映射 n-n 关系,单向n-n,双向n-n

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

  3. [原创]java WEB学习笔记85:Hibernate学习之路-- -映射 一对一关系 ,基于主键方式实现

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

  4. [原创]java WEB学习笔记84:Hibernate学习之路-- -映射 一对一关系 ,基外键的方式实现

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

  5. Hibernate学习---第八节:继承关系的映射配置

    1.单表继承 (1).实体类,代码如下: package learn.hibernate.bean; import java.util.Date; /** * 持久化类设计 * 注意: * 持久化类通 ...

  6. [原创]java WEB学习笔记82:Hibernate学习之路---映射 一对多关联关系,配置,CRUD方法测试及注意点

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

  7. 【hibernate】映射继承关系

    [hibernate]映射继承关系 转载:https://www.cnblogs.com/yangchongxing/p/10405151.html ========================= ...

  8. [原创]java WEB学习笔记81:Hibernate学习之路--- 对象关系映射文件(.hbm.xml):hibernate-mapping 节点,class节点,id节点(主键生成策略),property节点,在hibernate 中 java类型 与sql类型之间的对应关系,Java 时间和日期类型的映射,Java 大对象类型 的 映射 (了解),映射组成关系

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

  9. [原创]java WEB学习笔记77:Hibernate学习之路---Hibernate 版本 helloword 与 解析,.环境搭建,hibernate.cfg.xml文件及参数说明,持久化类,对象-关系映射文件.hbm.xml,Hibernate API (Configuration 类,SessionFactory 接口,Session 接口,Transaction(事务))

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

随机推荐

  1. JDBC(三)数据库连接池(DBCP、C3P0)

    前言 这段时间状态有一点浮躁,希望自己静下心来.还有特别多的东西还没有学懂.需要学习的东西非常的多,加油! 一.JDBC复习 Java Data Base Connectivity,java数据库连接 ...

  2. common lisp的宏的工作模式

    (defmacro our-expander (name) ‘(get ,name ’expander))(defmacro our-defmacro (name parms &body bo ...

  3. Maven 设置Maven源/镜像

    在Eclipse/ InteliJ Idea使用Maven时,企业提供的本地仓库经常有些Jar包下载不下来,所以.配置Maven设置国内镜像对开发人员来说是必不可少的.今天写一篇自己配制的Maven镜 ...

  4. Python中subplots_adjust函数的说明

    使用subplots_adjust一般会传入6个参数,我们分别用A,B,C,D,E,F表示.然后我们对图框建立坐标系,将坐标轴原点定在左下角点,并将整个图框归一化,即横纵坐标都是0到1之间.从下图中可 ...

  5. JavaScript系列----一切皆是对象

    1.判断对象类型 1.1.typeof 运算符 首先要认识到,typepof是一个运算符,其运算需要一个参数,返回值是参数的类型. typeof使用方法 typeof parameter //使用方法 ...

  6. JS中的循环---最全的循环总结

    在讲循环的之前,先知道一下循环结构的执行步骤 1.声明循环变量: 2.判断循环条件; 3.执行循环体操作: 4.更新循环变量: 5.然后循环执行2-4,直到条件不成立,跳出循环. 1while循环 v ...

  7. 设计模式的征途—23.解释器(Interpreter)模式

    虽然目前计算机编程语言有好几百种,但有时人们还是希望用一些简单的语言来实现特定的操作,只需要向计算机输入一个句子或文件,就能按照预定的文法规则来对句子或文件进行解释.例如,我们想要只输入一个加法/减法 ...

  8. 发布npm时遇到的两个小问题,解决方法

    1.出现这个错误 no_perms Private mode enable, only admin can publish this module 错误输出内容 npm ERR! publish Fa ...

  9. crontab中使用python无法执行

    手动执行可以的,但是在crontab中却无法执行,在网上搜了一圈,给出的结论是将相对路径改成绝对路径. 改了之后解决这个问题. 是不是依赖某些环境变量,linux 里的 cron 只有几个基本的环境变 ...

  10. Spring Boot中采用Mockito来mock所测试的类的依赖(避免加载spring bean,避免启动服务器)

    最近试用了一下Mockito,感觉真的挺方便的.举几个应用实例: 1,需要测试的service中注入的有一个dao,而我并不需要去测试这个dao的逻辑,只需要对service进行测试.这个时候怎么办呢 ...