zoukankan      html  css  js  c++  java
  • Hibernate笔记——表的的4种继承关系

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

    =====================================


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

    对象模型(Java类结构)

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


    Employee.java

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

     

    Skiller.java

     

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

     

    Sales.java

     

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

     

     

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

    只需更改Employee.hbm.xml

     

    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.     
    6. <hibernate-mapping package="domain">    
    7.     <class name="Employee" discriminator-value="0">    
    8.         <id name="id">    
    9.             <generator class="native"/>    
    10.         </id>    
    11.         <discriminator column="type" type="int"></discriminator>    
    12.         <property name="name"></property>       
    13.         <many-to-one name="dpt" column="dpt_id" lazy="false"></many-to-one>    
    14.         <subclass name="Skiller" discriminator-value="1">    
    15.             <property name="skill" ></property>    
    16.         </subclass>    
    17.         <subclass name="Sales" discriminator-value="2">    
    18.             <property name="sell"></property>    
    19.         </subclass>    
    20.     </class>    
    21. </hibernate-mapping>   

     

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

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

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

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

     

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

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



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

     

    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.     
    6. <hibernate-mapping package="domain">    
    7.     <class name="Employee">    
    8.         <id name="id">    
    9.             <generator class="native"/>    
    10.         </id>    
    11.         <property name="name"></property>       
    12.         <many-to-one name="dpt" column="dpt_id" lazy="false"></many-to-one>    
    13.         <joined-subclass name="Skiller">    
    14.             <key column="employee_id"></key>    
    15.             <property name="skill"></property>    
    16.         </joined-subclass>    
    17.         <joined-subclass name="Sales">    
    18.             <key column="employee_id"></key>    
    19.             <property name="sell"></property>    
    20.         </joined-subclass>    
    21.     </class>    
    22. </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

     

    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.     
    6. <hibernate-mapping package="domain">    
    7.     <class name="Employee" discriminator-value="0">    
    8.         <id name="id">    
    9.             <generator class="native"/>    
    10.         </id>    
    11.         <discriminator column="type" type="int"/>    
    12.         <property name="name"></property>       
    13.         <many-to-one name="dpt" column="dpt_id" lazy="false"></many-to-one>    
    14.         <subclass name="Skiller" discriminator-value="1">    
    15.                 <property name="skill"></property>        </subclass>    
    16.         <subclass name="Sales" <strong><span style="color: #ff0000;">discriminator-value="2"</span></strong>>    
    17.                 <join table="sales">    
    18.             <key column="employee_id"></key>    
    19.             <property name="sell"></property>    
    20.                 </join>    
    21.         </joined-subclass>    
    22.     </class>    
    23. </hibernate-mapping>    

     

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



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

    Employee.hbm.xml

     

    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”就不会有表与之对应。 

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

  • 相关阅读:
    FPGA 设计怎样进行面积优化(逻辑资源占用量优化)
    实现文件下载的java代码
    java推断字符串是否为乱码
    cocos2dx 制作单机麻将(二)
    CPU 风扇清理灰尘加油全过程图解
    初识 Cloudera Impala
    怎样设计接口?
    Android ViewPager使用具体解释
    php反射类 ReflectionClass
    memwatch的使用
  • 原文地址:https://www.cnblogs.com/pwc1996/p/4839142.html
Copyright © 2011-2022 走看看