? ? ?前幾篇博文中講到了常用的幾種關聯映射。其實Hibernate中還有一種“省勁兒”的映射,那就是——“繼承映射”。
? ? ?學了這么多的關系映射了,繼承映射,從字面上也能了解到猜到幾分。沒錯,繼承映射就是為繼承樹而設置的一種映射方案。
? ? ?繼承映射的實現有三種策略:
- 單表繼承。每棵類繼承樹使用一個表
- 類表繼承。每個子類生成一個表。
- 具體表繼承。每個類生成一個表。
? ? 我們還是用實例來說明一下,直接上圖吧:

? ? ?Pig和Bird都繼承自Animal,它們都有id,name,sex,但是Pig主要看weight,而Bird主要看height,此時如果把這些數據存入到數據庫中,可以有3種方案,正好對應3種策略。
? ? ?①. 只生成一個table,對應的繼承映射策略是“單表繼承”。如圖:

? ? ?②. 每個類生成一個table,對應的繼承策略是“類表繼承”。如圖:

? ? ③.?生成3張表,對應的策略是“具體表繼承”。如圖:

? ? ?相信大家更愿意看代碼,那就用代碼說一下吧:
~~~
public class Animals {
private int id;
private String name;
private boolean sex;
//此處省略get,set方法
}
public class Bird extends Animals {
private int height;
//此處省略get,set方法
}
public class Pig extends Animals {
private int weight;
//此處省略get,set方法
}
~~~
? ? ?第一種對應的映射文件:使用discriminator和subclass標簽
~~~
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.bjpowernode.hibernate">
<class name="Animals" table="t_animals" lazy="false">
<id name="id">
<generator class="native"/>
</id>
<discriminator column="type" type="string"></discriminator>
<property name="name"/>
<property name="sex"></property>
<subclass name="Pig" discriminator-value="P">
<property name="weight"></property>
</subclass>
<subclass name="Bird" discriminator-value="B">
<property name="height"></property>
</subclass>
</class>
</hibernate-mapping>
~~~
? ? ?discriminator,英文解釋是“辨別器”。它是用于設置辨別數據的字段,放在id下面,同時使用subclass來配置不同的類,設置discriminator-value,來辨別不同的數據。
? ? 第二種映射文件:使用union-subclass標簽
~~~
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.bjpowernode.hibernate">
<class name="Animals" table="t_animals" abstract="true">
<id name="id">
<!-- 不能使用native,因為自增會出現兩個表一樣的id -->
<generator class="assigned"/>
</id>
<property name="name"/>
<property name="sex"/>
<union-subclass name="Pig" table="t_pig">
<property name="weight" />
</union-subclass>
<union-subclass name="Bird" table="t_bird">
<property name="height" />
</union-subclass>
</class>
</hibernate-mapping>
~~~
? ? 第三種映射文件:使用joined-subclass標簽
~~~
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.bjpowernode.hibernate">
<class name="Animals" table="t_animals" lazy="false">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<property name="sex"/>
<joined-subclass name="Pig" table="t_pig">
<key column="pid" />
<property name="weight" />
</joined-subclass>
<joined-subclass name="Bird" table="t_bird">
<key column="bid" />
<property name="height" />
</joined-subclass>
</class>
</hibernate-mapping>
~~~
? ? ?以上三種策略,各有優缺點:
- 單表繼承。查詢速度最快,效率高,但是存在冗余字段。
- 類表繼承。層次清楚,無冗余;但是如果使用自增主鍵方式會產生重復主鍵。需要使用手動分配主鍵。
- 具體表繼承。層次最明了,這是優點,也是缺點,而且數據操作效率不高。
- 前言
- Struts 簡單小結
- 深入淺出了解Struts的處理流程(有圖有真相)
- struts標簽+jstl標簽之國際化實例
- 一口一口吃掉Hibernate(二)——別被世俗蒙蔽了雙眼:Hibernate中Session之get和load方法的真正區別
- 一口一口吃掉Hibernate(一)——使用SchemaExport生成數據表
- 一口一口吃掉Hibernate(三)——Hibernate給表和字段設置前后綴及分隔符
- 一口一口吃掉Hibernate(四)——多對一單向關聯映射
- 一口一口吃掉Hibernate(五)——一對多單向關聯映射
- 一口一口吃掉Hibernate(六)——多對多關聯映射
- 一口一口吃掉Hibernate(七)——繼承映射
- 一口一口吃掉Hibernate(八)——Hibernate中inverse的用法
- 一覽Spring全貌
- 包辦婚姻的Spring IoC
- 3幅圖讓你了解Spring AOP
- Spring Aop實例之xml配置
- Spring Aop實例之AspectJ注解配置