在類繼承的關系模式下,hibernate的實作繼承的方式有三種。簡單的總結一下這三種不同的繼承映射方式。
就拿上面這張圖來說吧。Animal作為一個抽象類出現,Pig有自己的weight屬性,Bird也有自己的height屬性,他們都有公共的屬性name和sex。
整棵類樹一張表
這種方式是将這個類樹上表示的所有資訊都放在一張表中來儲存。隻是用一個标志性字段将pig和Bird來區分開就行。
具體的映射代碼:
<class name="com.bjpowernode.hibernate.Animal" table="t_animal">
<id name="id">
<generator class="native"/>
</id>
<discriminator column="type" type="string"/>
<property name="name"/>
<property name="sex"/>
<subclass name="com.bjpowernode.hibernate.Pig" discriminator-value="P">
<property name="weight"/>
</subclass>
<subclass name="com.bjpowernode.hibernate.Bird" discriminator-value="B">
<property name="height"/>
</subclass>
</class>
這裡通過subclass标簽來标明子類。discriminator來區分子類,在子類中會通過discriminator-value來區分子類在資料表中所存放的值。
在存儲時,此字段不用認為的指派。很明顯,這種方式會造成資料庫表中大量備援字段同時檢視時不夠友善。
每個類一張表
此種方式是UML圖中涉及到的3個種類的分别放在3張表中。Pig和Bird都通過id來與Animal進行關聯。
<class name="com.bjpowernode.hibernate.Animal" table="t_animal">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<property name="sex"/>
<joined-subclass name="com.bjpowernode.hibernate.Pig" table="t_pig">
<key column="pig_id"/>
<property name="weight"/>
</joined-subclass>
<joined-subclass name="com.bjpowernode.hibernate.Bird" table="t_bird">
<key column="bid"/>
<property name="height"/>
</joined-subclass>
</class>
這裡用了joined-subclass 來标志子類。通過key來進行與animal表連接配接,作為子表的主鍵。
此種方式的優點是表中無備援字段,結構清晰。缺點是:無論是在加載時,還是存儲時,繼承的層次越多,關聯的表就越多,操作就會越麻煩。
每個具體類一張表
這裡具體的類是指不是抽象的類。比如Pig是具體的類,Bird是一個具體的類。
<class name="com.bjpowernode.hibernate.Animal" table="t_animal" abstract="true">
<id name="id">
<generator class="assigned"/>
</id>
<property name="name"/>
<property name="sex"/>
<union-subclass name="com.bjpowernode.hibernate.Pig" table="t_pig">
<property name="weight"/>
</union-subclass>
<union-subclass name="com.bjpowernode.hibernate.Bird" table="t_bird">
<property name="height"/>
</union-subclass>
</class>
這裡通過union-subclass來标明子類。abstract=“true”不會生成抽象類的表。這種方式的id主鍵不能設定為自增長。
必須手動配置設定。如果繼承的子類過多,就會很麻煩。
以上三種方式就是繼承映射中涉及到的幾種表結構方式。三種方式各自有各自的優缺點。通常還是采用第一種方式更加友善。