甜咖啡

我的IT空间

Hibernate继承关系映射

类继承关系映射
(1)DB表之间不存在继承关系,要把JavaBean中的继承关系映射到关系数据库中的有三种映射方式:
·每个类建一张表
·所有类建一张表
·只为具体类建表

eg. 以公司Company(一方)和员工Employee(多方),Employee有两个子:类小时工HourlyEmployee和正式员工SalariedEmployee


1)每个类建一张表
可以有效减少数据冗余,减少字段,查询效率不很高。
配置文件:
Company.hbm.xml
<class name="Company" table="company">
   <id name="oid" column="oid" >
        <generator class="native">
        </generator>
   </id>
   <property name="name" type="string"/>
   <!-- Company与Employee是多态关联,
    但是由于DB没有描述Employee类和它的两个子类的继承关系,
    因此无法映射Company类的employees集合,
    所以该文件仅仅映射了Company的id和name属性 -->
</class>
<一>:需要针对每个类写映射配置文件,就和普通的单表映射的xml文件相同
Employee.hbm.xml
<class name="Employee" table="employee">
   <id name="oid" column="oid" >
        <generator class="native">
        </generator>
   </id>
   <property name="name"/>

</class>

HourlyEmployee.hbm.xml
<class name="HourlyEmployee" table="hourly">
   <id name="oid" column="oid" >
        <generator class="native">
        </generator>
   </id>
   <property name="name"/>
   <property name="rate"></property>
   <many-to-one name="company" class="Company"
    column="companyid" cascade="save-update"></many-to-one>
</class>

SalaryEmployee.hbm.xml
<class name="SalariedEmployee" table="salaried">
   <id name="oid" column="oid" >
        <generator class="native">
        </generator>
   </id>
   <property name="name"/>
   <property name="salary"></property>
  
   <many-to-one name="company" class="Company"
    column="companyid" cascade="save-update"></many-to-one>
</class>
采用这种独立映射方式的配置方法,在配置文件中没有定义这些类之间的任何关系,也就是说,三个类都是独立存在的。使用这种映射方式解决了相同属性必须使用相同字段名的限制,但是从父类继承的属性需要在每个子类中都进行相应的定义,造成属性配置的重复。
<二>也可以使用一个xml文件来进行映射,要使用<union-subclass>标签!!!
注意:这里不能使用id生成策略中的native,而是要指定特定的生成策略。
Employee2.hbm.xml:
<class name="Employee" table="employee">
   <id name="oid" column="oid" >
       <generator class="hilo">
           <param name="table">tt_hi</param>
           <param name="column">hi</param>
        </generator>
   </id>
   <property name="name"/>
  
    <union-subclass name="HourlyEmployee" table="hourly" >
     <property name="rate"></property>
     <many-to-one name="Company"
column="companyid" cascade="save-update">
</many-to-one>
    </union-subclass>
   
    <union-subclass name="SalariedEmployee"
table="salaried" >
     <property name="salary"></property>
     <many-to-one name="Company" column="companyid"
cascade="save-update">
</many-to-one>
    </union-subclass>
    </class>

使用这种方式除了每个子类对应一个表外,其定义方式与java对象的继承非常相似,即子类可以继承父类中公共的属性定义,解决了属性配置的重复,但是,造成了相同属性必须使用相同字段名的限制。
2)所有类建一张表
查寻效率比较高,但是会产生很多空间浪费,当子类中的非空约束,就不大适用了,这是对于子类要使用<subclass>标签表示。
配置文件:
Company2.hbm.xml:
<class name="Company" table="company">
   <id name="oid" column="oid" >
        <generator class="native">
        </generator>
   </id>
   <property name="name" type="string"/>
   <set name="employees"
cascade="all-delete-orphan" inverse="true">
    <key column="companyid"></key>
    <one-to-many class="Employee"/>
   </set>
   </class>
Employee3.hbm.xml:
<class name="Employee" table="employee2">
   <id name="oid" column="oid" >
       <generator class="native">
        </generator>
   </id>
   <property name="name" />
   <discriminator column="employee_type" type="string"/>

   <subclass name="HourlyEmployee"
discriminator-value="hourly">
    <property name="rate"></property>
     <many-to-one name="Company"
column="companyid" cascade="all">
</many-to-one>
   </subclass>
  
   <subclass name="SalariedEmployee"
discriminator-value="salaried">
   <property name="salary"></property>
     <many-to-one name="Company"
column="companyid" cascade="save-update">
</many-to-one>   
   </subclass>
</class>
使 用这种映射方式需要注意的是它通过<discriminator>标签(<discriminator column="employee_type" type="string"/>)增加一个字段(这里是employee_type字段)来标示某个记录是属于哪个实体对象的。通过< subclass>标记中的discriminator-value属性来定义哪个值代表哪个子类的持久化对象。
3)只为具体类建表
·适用于不使用多态的情况下
·跟每个类建一张表的区别:
① 每个类一张表的映射策略所建立的表示独立的,每个表都包括子类所自定义 的属性和由父类锁继承的属性的映射字段。
② 只为具体类建表,子类所对应的表只包括子类所定义的属性,而子类所对应的 表与父类所对应的表是通过外键来进行关联的,即当持久化一个子类时,需要在父 类的表和子类的表各增加一条记录,这两个记录通过外键来关联。
·好处:父类所定义的属性就在父类的表中进行映射,而子类所定义的属性就在子类的表中进行映射。避免了子类所定义的表中仍然需要定义父类属性的映射字段。
·映射文件中的子类可以使用<join-subclass>标签来表示,并且引用父类的主 键作为共享主键,就是不需要指定id生成策略
配置文件:
Company3.hbm.xml:
<class name="Company" table="company3">
   <id name="oid" column="oid" >
        <generator class="native">
        </generator>
   </id>
   <property name="name" type="string"/>
  
   <set name="employees" cascade="all-delete-orphan"
inverse="true">
    <key column="companyid"></key>
    <one-to-many class="Employee"/>
   </set>
</class>
Employee4.hbm.xml:
<class name="Employee" table="employee3">
   <id name="oid" column="oid" >
       <generator class="native">
        </generator>
   </id>
   <property name="name" />
  
   <joined-subclass name="HourlyEmployee" table="hourly2">
    <key column="oid"></key>
    <property name="rate"></property>
    <many-to-one name="Company" column="companyid"
cascade="save-update">
</many-to-one>
   </joined-subclass>

   <joined-subclass name="SalariedEmployee" table="salaried2">
    <key column="oid"></key>
    <property name="salary"></property>
    <many-to-one name="Company" column="companyid"
cascade="save-update">
</many-to-one>
   </joined-subclass>
</class>

posted on 2011-03-26 23:41 甜咖啡 阅读(486) 评论(0)  编辑  收藏


只有注册用户登录后才能发表评论。


网站导航:
 

导航

<2011年3月>
272812345
6789101112
13141516171819
20212223242526
272829303112
3456789

统计

常用链接

留言簿(1)

我参与的团队

随笔档案

搜索

最新评论

阅读排行榜

评论排行榜