Java类中有继承关系,相应的在hibernate中,也有继承关系,子类反应到数据库中,就有多种实现形式了,子类和父类可以映射到同一张表中,子类也可以单独映射成一张表,但是用不同的标签实现,子类表和父类表的关系也不同。在映射文件中,有三个标签可以实现继承关系,分别是:subclass、joined-subclass、union-subclass,先陈述一下这三个标签的区别:

subclass标签就是为子类嵌入父类的表中而设计的,而且要指定鉴别器,即用subclass一定要有判断类型的一个列,鉴别器指定记录属于哪个类型。但是subclass也提供了为子类设置单独的表的功能,即join标签。但是不管是内嵌表还是外部表,都得指定鉴别器。

joined-subclass标签,提供的功能是只能为子类设定外部表,而且没有鉴别器,即子类一张表,父类一张表,子类以父类的主键为外键。父类对应的表中,没有判断类型的列。

注意:这两个标签不能混用,若是只想要内嵌表,或者是既想要有内嵌表,又想要外部表,又或者是只想要外部表,那么只能使用subclass标签,需要注意的是,不论哪种方式,都要指定鉴别器,即父类对应的表中,一定有一个判断类型的列;而若是只想要外部表,又不想在父类对应的表中,要那个判断类型的列,那么只能使用join-subclass

union-subclass是将父类中的属性,添加到子类对应的表中去了。包括父类中的外键。union-class和前两个的区别就在于外键的不同,前两个标签,如果子类有单独对应的表的话,这个表的外键是其父类中的主键,而使用union-class,子类对应的表中的外键则和父类的外键是一样的,因为子类把父类继承的属性,也加到了自己的表当中。这样子类和父类的地位就相当了。不过这不是一种好的理解方式。如果是这样的话,那么就可以把父类设为抽象的类,并且在映射文件中,把父类设置为abstract="true",那么就不会再数据库中生成父类对应的表了,父类就只起到一个抽象的作用了。

下面列举员工和部门的例子说明,假设员工类还有两个子类:一个是技术人员,一个是销售人员:

[java] view plaincopy
  1. public class Employee {
  2. private int id;
  3. private String name;
  4. private Department depart;
  5. ……//set/get方法
  6. }
[java] view plaincopy
  1. public class Skiller extends Employee {
  2. private String skill;
  3. ……//set/get方法
  4. }
[java] view plaincopy
  1. public class Saler extends Employee {
  2. private String sale;
  3. private int age;
  4. ……//set/get方法
  5. }
[java] view plaincopy
  1. public class Department {
  2. private int id;
  3. private String name;
  4. private Set<Employee> emps;
  5. ……//set/get方法
  6. }

部门类的映射文件:

[html] view plaincopy
  1. <class name="Department">
  2. <id name="id">
  3. <generator class="native"/>
  4. </id>
  5. <property name="name"/>
  6. <set name="emps" inverse="true">
  7. <key column="depart_id"/>
  8. <one-to-many class="Employee"/>
  9. </set>
  10. </class>

(1)下面关键是员工类的映射文件,我们先来看使用subclass标签的情况:

[html] view plaincopy
  1. <class name="Employee" discriminator-value="0">
  2. <id name="id">
  3. <generator class="native"/>
  4. </id>
  5. <discriminator column="type" type="int"/><!-- 指定了鉴别器 -->
  6. <property name="name"/>
  7. <many-to-one name="depart" column="depart_id"/>
  8. <subclass name="Skiller" discriminator-value="1">
  9. <property name="skill"/>
  10. </subclass>
  11. <subclass name="Saler" discriminator-value="2">
  12. <property name="sale"/>
  13. </subclass>
  14. </class>

这种情况就是所谓的将整个继承树映射到同一个表当中,即子类的信息,全部映射到了父类对应的表中。注意,一定要指定鉴别器,它的作用是在父类的映射表中,添加了一个type的列,用来鉴别员工是属于哪个子类,并且在每个类的标签中要指定鉴别器值,如上例中用0表示是普通的员工,用1表示技术人员,用2表示销售人员。我们可以看看创建表的ddl语句:

[sql] view plaincopy
  1. CREATE TABLE `employee` (
  2. `id` int(11) NOT NULL,
  3. `type` int(11) NOT NULL,
  4. `name` varchar(255) DEFAULT NULL,
  5. `depart_id` int(11) DEFAULT NULL,
  6. `skill` varchar(255) DEFAULT NULL,
  7. `sale` varchar(255) DEFAULT NULL,
  8. PRIMARY KEY (`id`),
  9. KEY `FK4AFD4ACE972E0614` (`depart_id`),
  10. CONSTRAINT `FK4AFD4ACE972E0614` FOREIGN KEY (`depart_id`) REFERENCES `department` (`id`)
  11. ) ENGINE=InnoDB DEFAULT CHARSET=gbk

用这种方式有缺点有优点,缺点是在表中,会有很多的空值,假如又有了新的子类,那么就要修改表的结构,并且相应的空值会更多;优点是所有信息整合到一张表中,查询的效率高。

下面再来看subclass标签的第二种用法:

[html] view plaincopy
  1. <class name="Employee" discriminator-value="0"><!--  discriminator-value="0" -->
  2. <id name="id">
  3. <generator class="native"/>
  4. </id>
  5. <discriminator column="type" type="int"/><!-- 指定了鉴别器 -->
  6. <property name="name"/>
  7. <many-to-one name="depart" column="depart_id"/>
  8. <subclass name="Skiller" discriminator-value="1">
  9. <property name="skill"/>
  10. </subclass>
  11. <subclass name="Saler" discriminator-value="2">
  12. <join table="saler">
  13. <key column="emp_id"/>
  14. <property name="sale"/>
  15. </join>
  16. </subclass>
  17. </class>

改变的地方,主要是Saler类的标签,在subclass标签中用join标签,这样就为Saler子类单独映射了一个saler表,其主键为父类对应的表的主键。而Skiller类还是和父类映射到了一张表中。来看看Saler创建表的ddl语句:

[sql] view plaincopy
  1. CREATE TABLE `saler` (
  2. `emp_id` int(11) NOT NULL,
  3. `sale` varchar(255) DEFAULT NULL,
  4. PRIMARY KEY (`emp_id`),
  5. KEY `FK682490B3F739201` (`emp_id`),
  6. CONSTRAINT `FK682490B3F739201` FOREIGN KEY (`emp_id`) REFERENCES `employee` (`id`)
  7. ) ENGINE=InnoDB DEFAULT CHARSET=gbk

需要注意的一个地方是这个表的外键,外键和主键是一样的,都是父类表的主键。

(2)joined-subclass的使用

[html] view plaincopy
  1. <class name="Employee"><!--  discriminator-value="0" -->
  2. <id name="id">
  3. <generator class="native"/>
  4. </id>
  5. <property name="name"/>
  6. <many-to-one name="depart" column="depart_id"/>
  7. <joined-subclass name="Skiller" table="skiller">
  8. <key column="emp_id"/>
  9. <property name="skill"/>
  10. </joined-subclass>
  11. <joined-subclass name="Saler" table="saler">
  12. <key column="emp_id"/>
  13. <property name="sale"/>
  14. </joined-subclass>
  15. </class>

用joined-subclass只能创建为子类单独创建表,子类对应的表的主键和外键都是其父类的主键。注意,joined-subclass不能和subclass混合使用。

(3)union-subclass的使用

[html] view plaincopy
  1. <class name="Employee">
  2. <id name="id">
  3. <generator class="hilo"/>
  4. </id>
  5. <property name="name"/>
  6. <many-to-one name="depart" column="depart_id"/>
  7. <union-subclass name="Skiller" table="skiller">
  8. <property name="skill"/>
  9. </union-subclass>
  10. <union-subclass name="Saler" table="saler">
  11. <property name="age"/>
  12. <property name="sale"/>
  13. </union-subclass>
  14. </class>

注意,这里主键的生成方式就不能是自增的了,这里用的hilo方式,可以为子类的表分配和父类的表不同的主键。这样每个子类生成了一个表,并且结合了父类中的属性。生成的表的ddl语句为:

[sql] view plaincopy
  1. CREATE TABLE `skiller` (
  2. `id` int(11) NOT NULL,
  3. `name` varchar(255) DEFAULT NULL,
  4. `depart_id` int(11) DEFAULT NULL,
  5. `skill` varchar(255) DEFAULT NULL,
  6. PRIMARY KEY (`id`),
  7. KEY `FK4AFD4ACE972E06147ffd86be` (`depart_id`),
  8. CONSTRAINT `FK4AFD4ACE972E06147ffd86be` FOREIGN KEY (`depart_id`) REFERENCES `department` (`id`)
  9. ) ENGINE=InnoDB DEFAULT CHARSET=gbk

注意,这里的外键是部门类对应的表的主键,这是和上面两个标签的区别之处。若是将父类设置为抽象类,并且在class标签中设置abstract="true",那么父类就不会生成对应的表了。

hibernate——继承关系以及三个subclass标签的区别相关推荐

  1. hibernate继承关系映射方法(三)--每个具体类一张表TPC

    TPC:所谓是"每个具体类一张表(table per concrete class)"的意思是:使继承体系中每一个子类都对应数据库中的一张表.每一个子类对应的数据库表都包含了父类的 ...

  2. hibernate继承关系映射关系方法(二)--每个子类一张表

    TPS:所谓"每个子类一张表(Table Per Subclass)":父类一张表,每个子类一张表,父类的表保存公共有信息,子类的表只保存自己特有的信息 这种策略是使用<jo ...

  3. hibernate继承关系映射方法(一)--共享一张表

    对于如下关系: Person.java package com.hust.PO;public class Person {private Integer id;private String name; ...

  4. java继承 映射_hibernate继承关系映射和java反射机制的运用

    转:http://blog.csdn.net/derpvailzhangfan/article/details/1957946 ,感谢博主分享 Notes:hibernate元数据的运用:uuid的概 ...

  5. hibernate 表关系映射详解之继承关系

    举例:亚马逊的网上商城可以卖很多东西,比如说图书,电器,水果等等,那么我们以面向对象的理念去抽象一个商品类,他具有商品的共有属性,比如说上架时间,当前         价格,优惠价格等待,商品可以继承 ...

  6. Hibernate中的Entity类之间的继承关系之一MappedSuperclass

    在hibernate中,Entity类可以继承Entity类或非Entity类.但是,关系数据库表之间不存在继承的关系.那么在Entity类之间的继承关系,在数据库表中如何表示呢? Hibernate ...

  7. Hibernate继承映射

    Hibernate继承映射 在面向对象的程序领域中,类与类之间是有继承关系的,例如Java世界中只需要extends关键字就可以确定这两个类的父子关系,但是在关系数据库的世界中,表与表之间没有任何关键 ...

  8. web进修之—Hibernate 继承映射(5)

    先看三个类的继承关系,Payment是父类,CashPayment和CreditCardPayment是Payment的子类: view plaincopy to clipboardprint pub ...

  9. hibernate 继承映射

    在域模型中,类与类之间除了关联关系和聚集关系,还可以存在继承关系,在下图所示的域模型中,Deparment类和Employee类之间为一对多的双向关联关系,Employee类有两个子类:Skiller ...

  10. JPA和Hibernate的关系

    转载自:https://www.cnblogs.com/amoyzhu/p/5937717.html JPA Java Persistence API,是Java EE 5的标准ORM接口,也是ejb ...

最新文章

  1. BC30138: 无法在路径“C:\WINDOWS\TEMP\”中创建临时文件: 拒绝访问。
  2. HTML 元素居中的方法
  3. log4net环境配置
  4. (zt)说说大型高并发高负载网站的系统架构
  5. 注解形式控制器 数据验证,类型转换
  6. NachOS简述和源文件
  7. 在Mac上安装Linux的行为是否应该被鄙视?
  8. Ubuntu上面安装Mongo
  9. 【GPT-3】除了缺少点创意,GPT-3写出了及格的大学毕业论文,只需20分钟
  10. 7. where loop
  11. javascript+Java 实现MD5加密登录密码
  12. AAC音频的解码算法
  13. Android混淆和加固详解
  14. 心电信号越界怎么回事_一种心电信号处理方法
  15. 高效人士的七个管理习惯
  16. python pyinstaller使用方法_【python快手菜】pyinstaller使用指南
  17. PostScript 与 Encapsulated PostScript
  18. k8s.gcr.io、gcr.io仓库的镜像下载
  19. 关于pd.read_csv() 读数据的注意事项
  20. 如何使用CAD软件来修改表格中CAD字体颜色?

热门文章

  1. 疫情肆虐下,程序员们都在哪里?
  2. matlab从mp4文件中提取音频,如何提取mp4视频中的音频文件 将视频转换为MP3音频...
  3. POI 报错问题:Merged region A15 must contain 2 or more cells
  4. win10用户名与计算机名字一样,win10电脑账户名和其他信息怎么更改
  5. jQuery boxy
  6. 蛋白质ph稳定性计算机模拟,蛋白质分子设计.ppt
  7. 【软件技巧】【截图】浏览器自带的全网页截图工具
  8. VS2019的C++项目如何查看源文件(.h,.cc.cpp等)所在的工程
  9. unity, Animation crossfade需要两动画在时间上确实有交叠
  10. 论文写作,word首页脚注不显示编号