http://justsee.iteye.com/blog/1070588

一、继承关系_整个继承树映射到一张表

对象模型(Java类结构)

一个类继承体系一张表(subclass)(表结构)

Employee.java

  1. package com.taobao.hibernate.domain;
  2. public class Employee {
  3. private int id;
  4. private String name;
  5. private Department department;
  6. public int getId() {
  7. return id;
  8. }
  9. public void setId(int id) {
  10. this.id = id;
  11. }
  12. public String getName() {
  13. return name;
  14. }
  15. public void setName(String name) {
  16. this.name = name;
  17. }
  18. public Department getDepartment() {
  19. return department;
  20. }
  21. public void setDepartment(Department department) {
  22. this.department = department;
  23. }
  24. }

Skiller.java

  1. package com.taobao.hibernate.domain;
  2. public class Skiller extends Employee {
  3. private String skill;
  4. public String getSkill() {
  5. return skill;
  6. }
  7. public void setSkill(String skill) {
  8. this.skill = skill;
  9. }
  10. }

Sales.java

  1. package com.taobao.hibernate.domain;
  2. public class Sales extends Employee {
  3. private String sell;
  4. public String getSell() {
  5. return sell;
  6. }
  7. public void setSell(String sell) {
  8. this.sell = sell;
  9. }
  10. }<span style="white-space: normal;">
  11. </span>

这里我们考虑设计数据库是把员工都涉及在一张表,那么如何区分员工种类呢?加入员工类型这个字段来区别。

只需更改Employee.hbm.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE hibernate-mapping PUBLIC
  3. "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
  4. "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
  5. <hibernate-mapping package="domain">
  6. <class name="Employee" discriminator-value="0">
  7. <id name="id">
  8. <generator class="native"/>
  9. </id>
  10. <discriminator column="type" type="int"></discriminator>
  11. <property name="name"></property>
  12. <many-to-one name="dpt" column="dpt_id" lazy="false"></many-to-one>
  13. <subclass name="Skiller" discriminator-value="1">
  14. <property name="skill" ></property>
  15. </subclass>
  16. <subclass name="Sales" discriminator-value="2">
  17. <property name="sell"></property>
  18. </subclass>
  19. </class>
  20. </hibernate-mapping>

<discriminator column="type" type="int"/>中的type默认值是string。

所有子类定义的字段不能为空。

使用了<discriminator column="type" type="int"></discriminator>这个标签,就是映射了type字段,然后Hibernate会根据type字段的值来确定从数据库中取过来的是什么对象。

在查询的get方法时,也可以自动识别,会自动用相对应的对象去封装数据。

一个继承树映射到一张表的话,会有很多空字段,不符合关系数据库的设计模式。

二、继承关系_每个类映射到一张表


 这时候Employee.hbm.xml配置文件信息如下:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE hibernate-mapping PUBLIC
  3. "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
  4. "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
  5. <hibernate-mapping package="domain">
  6. <class name="Employee">
  7. <id name="id">
  8. <generator class="native"/>
  9. </id>
  10. <property name="name"></property>
  11. <many-to-one name="dpt" column="dpt_id" lazy="false"></many-to-one>
  12. <joined-subclass name="Skiller">
  13. <key column="employee_id"></key>
  14. <property name="skill"></property>
  15. </joined-subclass>
  16. <joined-subclass name="Sales">
  17. <key column="employee_id"></key>
  18. <property name="sell"></property>
  19. </joined-subclass>
  20. </class>
  21. </hibernate-mapping>

<joined-subclass name="Sales">

子类对应类名为Sales,表名为Sales

<key column="employee_id"></key>

通过employee_id与Employee表关联

<property name="sell"></property>

设置sell属性

</joined-subclass>

这样就完成了Hibernate的配置,生成的表符合上面所说的表结构。

Hibernate: insert into Department (name) values (?)

插入部门

Hibernate: insert into Employee (name, dpt_id) values (?, ?)

插入销售员工到员工表

Hibernate: insert into Sales (sell, employee_id) values (?, ?)

插入销售员工到销售员工表

Hibernate: insert into Employee (name, dpt_id) values (?, ?)

插入技术员工到员工表

Hibernate: insert into Skiller (skill, employee_id) values (?, ?)

插入技术员工到技术员工表

5条插入信息

现在又有问题了,既然用到了多表关联,那么删除这些级联操作会怎么样呢

Hibernate: delete from Sales where employee_id=?

Hibernate: delete from Employee where id=?

发现两条delete语句很好的将员工信息删除掉了。

这里还需要注意的是,查询的时候避免使用多态查询,多表连接查询效率较低,最好明确指定查询的类别,不要直接用员工类进行查询。

三、继承关系_鉴别器与内连接相结合

把属性不多的类对应的列放到父类列中,把子类属性多的单独用一个表。这里假设Sales有很多列

内容和上两篇没有什么大的区别,原理类似,只是标签上略有不同。

Employee.hbm.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE hibernate-mapping PUBLIC
  3. "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
  4. "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
  5. <hibernate-mapping package="domain">
  6. <class name="Employee" discriminator-value="0">
  7. <id name="id">
  8. <generator class="native"/>
  9. </id>
  10. <discriminator column="type" type="int"/>
  11. <property name="name"></property>
  12. <many-to-one name="dpt" column="dpt_id" lazy="false"></many-to-one>
  13. <subclass name="Skiller" discriminator-value="1">
  14. <property name="skill"></property>        </subclass>
  15. <subclass name="Sales" <strong><span style="color: #ff0000;">discriminator-value="2"</span></strong>>
  16. <join table="sales">
  17. <key column="employee_id"></key>
  18. <property name="sell"></property>
  19. </join>
  20. </joined-subclass>
  21. </class>
  22. </hibernate-mapping>

四、继承关系_每.类映射一张独立表


 可见表之间都是独立的,没有关联的。

Employee.hbm.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE hibernate-mapping PUBLIC
  3. "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
  4. "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
  5. <hibernate-mapping package="domain">
  6. <class name="Employee">
  7. <id name="id">
  8. <generator class="hilo"/>
  9. </id>
  10. <property name="name"></property>
  11. <many-to-one name="dpt" column="dpt_id" lazy="false"></many-to-one>
  12. <union-subclass name="Skiller">
  13. <property name="skill"></property>
  14. </union-subclass>
  15. <union-subclass name="Sales">
  16. <property name="sell"></property>
  17. </union-subclass>
  18. </class>
  19. </hibernate-mapping>

这种方式的局限在于,如果一个属性在超类中做了映射,其字段名必须与所有子类表中定义的相同(Hibernate可能在后续版本中放宽此限制)。除此之外,使用union-subclass映射策略是不可使用identity的主键生成策略,因为同一类继承层次中所有实体类都需要使用同一个主键种子(即多个持续化实体对应的记录的主键是连续的)。受此影响,也不应该使用native主键生成策略,因为native会根据数据库来选择使用identity或sequence策略。,所以不要native,identity,sequence主键生成策略,可以是increment,hilo。

如果父类是abstract=”true”就不会有表与之对应。

隐式多态,映射文件没有联系,限制比较多很少使用。

hibernate继承(转)的更多相关文章

  1. 转Hibernate继承

    hibernate继承映射 以下测试是在mysql中进行的. 1.单表方式 Animal.java @Entity @Inheritance(strategy=InheritanceType.SING ...

  2. 【JavaEE】Hibernate继承映射,不用多态查询只查父表的方法

    几个月前,我在博问里面发了一个问题:http://q.cnblogs.com/q/64900/,但是一直没有找到好的答案,关闭问题以后才自己解决了,在这里分享一下. 首先我重复一下场景,博问里面举的动 ...

  3. SSH开发实践part3:hibernate继承映射

    0 大家好.上次讲了关于hibernate中双向1-N的映射配置,可以参考:http://www.cnblogs.com/souvenir/p/3784510.html 实际项目中,对象间的关系比较复 ...

  4. Hibernate继承映射

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

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

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

  6. Hibernate继承类的实现

    版权声明:本文为博主原创文章,如需转载请标注转载地址. 博客地址:http://www.cnblogs.com/caoyc/p/5603724.html  对于继承关系类的映射.比如在论坛中文章(Ar ...

  7. hibernate 继承映射关系( SINGLE_TABLE)

    三种继承映射关系.   1,SINGLE_TABLE   person student  teacher 在一个表中,student和teacher继承自person,通过一个Discriminato ...

  8. Hibernate 继承映射可能会遇到的错误

    问题: 我们在配置hibernate的时候,默认是会配置下面的两个属性的 <property name="hibernate.default_catalog">hibe ...

  9. Hibernate继承注解

    hibernate应用中,继承的用途或目的主要有两点: 组件化:故明思义,把重复性的代码抽取成组件,以便重用和维护.hibernate应用中,一些重复的字段,重复的映射配置,就需要抽取成组件. 多态性 ...

随机推荐

  1. 结构化查询语言(SQL)数据类型

    简要描述一下结构化查询语言中的五种数据类型:字符型,文本型,数值型,逻辑型和日期型. 字符型 VARCHARVS CHAR VARCHAR型和CHAR型数据的这个差别是细微的,但是非常重要.他们都是用 ...

  2. CVTE实习面经

    一个月的实习都结束了,我才把这篇面经放出来...可能有记得不太清楚的地方,还请多多见谅. 第一次面试是在5月中旬. 这次面试问的主要是基础的问题吧,就是C和C++的基础问题,我记得有问到下面几个问题 ...

  3. js高阶函数

    我是一个对js还不是很精通的选手: 关于高阶函数详细的解释 一个高阶函数需要满足的条件(任选其一即可) 1:函数可以作为参数被传递 2:函数可以作为返回值输出 吧函数作为参数传递,这代表我们可以抽离一 ...

  4. jsp实现回车登录

    <body onkeydown="if(event.keyCode==13){login()}"> 内容0...... </body> 注:body里面加上 ...

  5. OpenResty(nginx_lua_module)做ES代理以及备份ES数据

    #user nobody; worker_processes 1; #error_log logs/error.log; #error_log logs/error.log notice; #erro ...

  6. JS-数组的方法

    var arr = [ 1,2,3 ];arr.push( 'abc' );//从后面加 arr.unshift( 0 );//从前面加 arr.pop()//从后面删除 arr.shift()//从 ...

  7. css3 风车旋转

    <style> .box{width:400px;height:400px;margin:100px auto;transition:1s;} .box div{width:180px;h ...

  8. HtmlAgilityPack组件

    HtmlAgilityPack组件用于解析Html字符串,一个典型的应用场景是用于网页爬虫. 示例程序 using Common.Tools; using Datebase.Entity; using ...

  9. [转载]Firebird与MySQL:一个使用者的体会

    老板要我开发一个LINUX平台上的数据库项目,要求一定要用开源免费数据库.我知道这个数据库必须能够上网操作,同时作为公司的核心骨干数据库,除了必须是稳定的存储数据库外还必须有很强的数据和数据库控管功能 ...

  10. CentOS防火墙问题

    问题背景 在Vmware虚拟机中安装了 CentOS 7 的 Linux 版本,并在其中安装了 Oracle 11g 数据库,数据库可以在虚拟机中顺利启动,本地主机也可以 ping 通 linux.准 ...