原文: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笔记——表的的4种继承关系的更多相关文章

  1. C++中的三种继承关系

    C++中的三种继承关系 先看类中声明成员时的三种访问权限 public : 可以被任意实体访问 protected : 只允许子类及本类的成员函数访问 private : 只允许本类的成员函数访问 在 ...

  2. Hibernate之jpa实体映射的三种继承关系

    在JPA中,实体继承关系的映射策略共有三种:单表继承策略(table per class).Joined策略(table per subclass)和Table_PER_Class策略. 1.单表继承 ...

  3. <读书笔记>Javascript系列之6种继承(面向对象)

    写在前面: 以下三选一: 阅读博文JavaScript 对象详解. 阅读<JavaScript权威指南>第6章. 阅读<JavaScript高级程序设计>第6章. 注意:只需要 ...

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

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

  5. Hibernate逍遥游记-第10章 映射继承关系-003继承关系树中的每个类对应一个表(joined-subclass)

    1. 2. <?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate ...

  6. Hibernate逍遥游记-第10章 映射继承关系-002继承关系树中的根类对应一个表(discriminator、subclass)

    1. 2. <?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate ...

  7. Hibernate逍遥游记-第10章 映射继承关系-001继承关系树中的每个具体类对应一个表

    1. 2. <?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate ...

  8. hibernate笔记--继承映射关系的三种实现方式

    单表继承映射(一张表): 假设我们现在有三个类,关系如下: Person类有两个子类Student和Teacher,并且子类都具有自己独有的属性.这种实体关系在hibernate中可以使用单表的继承映 ...

  9. C++中的类继承(1) 三种继承方式

    继承是使代码可以复用的重要手段,也是面向对象程序设计的核心思想之一.简单的说,继承是指一个对象直接使用另一对象的属性和方法.继承呈现了 面向对象程序设 计的层次结构, 体现了 由简单到复杂的认知过程. ...

随机推荐

  1. iTween基础之Shake(摆动)

    一.基础介绍:二.基础属性 原文地址 :http://blog.csdn.net/dingkun520wy/article/details/50836780 一.基础介绍 ShakePosition: ...

  2. java 顺序表

    想看看java版的数据结构,了解一下树的一些操作,写了个顺序表熟悉一下 package com.sqlist; /** * @author xiangfei * 定义一个顺序表 * */ public ...

  3. 圆形DIV

    <head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" ...

  4. 【Python】vim7.4 配置python2.6支持Gundo

    问题描述:          vim7.4 配置python2.6支持Gundo   参考资料:         (1)  http://sjl.bitbucket.org/gundo.vim/    ...

  5. Poj 1050 分类: Translation Mode 2014-04-04 09:31 103人阅读 评论(0) 收藏

    To the Max Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 39058   Accepted: 20629 Desc ...

  6. Poj 1032 分类: Translation Mode 2014-04-04 09:09 111人阅读 评论(0) 收藏

    Parliament Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 16521   Accepted: 6975 Descr ...

  7. Curse of Dimensionality

    Curse of Dimensionality Curse of Dimensionality refers to non-intuitive properties of data observed ...

  8. Win32 Plus Extra Height of Caption Bar

    you set the size of the non-client area by handling the WM_NCCALCSIZE message. But don't do this unl ...

  9. [nowCoder] 二进制中1的个数

    题目描述 输入一个整数,输出该数二进制表示中1的个数.其中负数用补码表示.     class Solution { public: int NumberOf1(int n) { ; while(n) ...

  10. Hadoop伪分布模式配置

    本作品由Man_华创作,采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可.基于http://www.cnblogs.com/manhua/上的作品创作. 请先按照上一篇文章H ...