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>