Hibernate對映詳解(六)--繼承對映
在物件中,是有繼承的概念的。那既然Hibernate實現表採用的是一種面向物件的方式,則當然也少不了繼承的概念。舉個例子來說,小豬和小鳥都是動物,他們都有一些共同的屬性。如他們都有一個id,有姓名,有性別。但是呢,小豬有重量,小鳥遊高度。(just舉例哈)。這就是一個繼承關係了,在Hibernate中我們怎麼實現它呢?先把這個情況用圖來表示一下
實現後表的形式為:
這三種方式所生成的表格想必大家不難理解。那hibernate中具體是怎麼實現的呢?
這三種方式的實體類構造完全是一樣的。實現形式如下:
public class Pigextends privateintweight; } |
public class Birdextends Animal { privateintheight; } |
public class Animal { privateintid; private Stringname; privatebooleansex; } |
關聯對映的對映檔案都是與實體相對應的,每個實體對應一個對映檔案。繼承對映就省去了這些麻煩。他們只需要一個對映檔案就搞定了。我們看一下不同方式的繼承對映檔案是如何實現的。要注意,繼承對映中對映檔案的名稱為Extends.hbm.xml
每個類一張表 |
<hibernate-mappingpackage="com.bjpowernode.hibernate"> <classname="Animal"table="t_animal"> <idname="id"> <generatorclass="native"/> </id> <propertyname="name"/> <propertyname="sex"/>
<joined-subclassname="Pig"table="t_pig" <keycolumn="pid"/> <propertyname="weight"/> </joined-subclass> <joined-subclassname="Bird"table="t_bird"> <keycolumn="bid"/> <propertyname="height"/> </joined-subclass> </class> </hibernate-mapping> |
每個具體類一張表(要注意一下,在儲存 物件的時候id不能重複,所以此處主鍵不 能採用自動新增的形式,要手動新增) |
<hibernate-mappingpackage="com.bjpowernode.hibernate"> <classname="Animal"table="t_animal"abstract="true"> <idname="id"> <generatorclass="assigned"/> </id> <propertyname="name"/> <propertyname="sex"/> <union-subclassname="Pig"table="t_pig"> <propertyname="weight"/> </union-subclass> <union-subclassname="Bird"table="t_bird"> <propertyname="height"/> </union-subclass> </class> </hibernate-mapping> |
每顆繼承樹一張表 |
<hibernate-mappingpackage="com.bjpowernode.hibernate"> <classname="Animal"table="t_animal"lazy="false"> <idname="id"> <generatorclass="native"/> </id> <discriminatorcolumn="type"type="string"/> <propertyname="name"/> <propertyname="sex"/> <subclassname="Pig"discriminator-value="P"> <propertyname="weight"/> </subclass> <subclassname="Bird"discriminator-value="B"> <propertyname="height"/> </subclass> </class> </hibernate-mapping> |
繼承對映,對於鑑別值的儲存時hibernate自動完成的,不需要我們手動去儲存,其他的儲存與關聯對映沒有區別。但是,對於查詢來說,他就發揮出他的優勢了。多型查詢的功能,你不必確切的知道他屬於哪個類,只要知道父類就能完成查詢功能。get和hql方式是完全支援多型查詢的,但是load有些特殊。他在lazy設定為false的情況下支援多型查詢,當為true時,則不支援。我們看一個例子體會一下多型查詢。
例一: Animal a = (Animal)session.load(Animal.class, 1); System.out.println(a.getName()); hibernate可以自動鑑別出你是哪個類的例項,取出相應的值 |
例二: Animal a = (Animal)session.load(Animal.class, 1); //因為load預設支援lazy,所以我們看到的是Animal的代理 //所以採用instanceof無法鑑別出真正的型別Pig //所load在此情況下是不支援多型查詢的 //多型查詢:hibernate在載入資料的時候,能夠採用instancof鑑別出其真正的型別 if (ainstanceof Pig) { System.out.println(a.getName()); }else { System.out.println("不是豬!"); } 通過instanceof可以自動鑑別出具體是哪個物件的例項。 |
通過instanceof可以自動鑑別出具體是哪個物件的例項。到這裡,繼承對映就介紹完了。對它的三種實現形式,我採用表格比照的方式,將他們的實現形式以及實現的結果進行了展示。三種方式適合與不同的場景。具體什麼時候應用根據他們的實現結果,根據需求我們在判斷吧!