標籤:style blog http java 使用 strong
前面幾種關係我們以前就經常用,對於繼承我們也並不陌生,經常接觸的類與類之間的繼承用extends關鍵字,那麼在表與表的關係中如何表示呢?下面我們來講繼承映射。
繼承有三種實現的策略,單表繼承,具體表繼承,類表繼承。下面來分析一下這三種方式
繼承關聯類別關係
單表繼承
每棵類繼承樹使用一個表,可知,這三個類在一張表中。如下表:
這張表包括了父類,子類的所有屬性,通過Type來區分是哪個子類。
物件模型映射到關聯式模式:
<classname="com.bjpowernode.hibernat.Animal" table="t_animal"><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>
每棵類繼承樹一張表,類繼承樹對應多個類,要把多個類的資訊放到一張表中,必須有某種機制來區分哪些記錄是屬於哪個類的。也就是上面discriminator欄位,用這個欄位的值來區分。
優缺點:表中引入了用來區分子類的欄位;如果某個子類的屬性不可為空,那麼在資料庫中不能設定該欄位非空,靈活性差;維護方便,只需要修改一張表;如果子類增加,那麼表中的冗餘欄位也會隨著增多。如果資料不是很多的話,效率是最好的。
具體表繼承
每個子類一個表,與父類所對應的表以一對一主鍵關聯的方式關聯起來,如下
animal表中儲存了子類的所有記錄,只記錄公用資訊。它們專屬的資訊儲存在子類表中。通過父表與子表的id來進行關聯。
物件模型映射到關聯式模式
<classname="com.bjpowernode.hibernat.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="bird"/><propertyname="height"/></joined-subclass></class>
該類繼承映射用<joined-subclass>標籤,用於指示父類與子類的關聯欄位。
優缺點:這種方式符合關聯式模式的設計原則,不存在冗餘,維護起來較方便,對每個類的修改只需要修改其對應的表,靈活性好;完全參照對象繼承的方式進行配置。另外層次清晰,但是如果類繼承的層次特別多,表特別多時,效率會很低,所以如果層次少的可以用此方式。
類表繼承
每個具體類一個表,根據上面的類圖看,共有兩張表,pig,bird各一張
每個子類對應的資料庫表不僅包括自身的屬性還包括父類的屬性。
物件模型映射到關聯式模式
<classname="com.bjpowernode.hibernat.Animal" table="t_animal"><idname="id"><generatorclass="native"/></id> <propertyname="name"/><propertyname="sex"/> <union-subclassname="Pig" table="t_pig"><keycolumn="pid"/><propertyname="weight"/></union-subclass> <union-subclassname="Bird" table="t_bird"><keycolumn="bird"/><propertyname="height"/></union-subclass></class>
該類型的繼承映射用<union-subclass>標籤,用於指示出該hbm檔案所表示的類的子類
優缺點:該方式符合關聯式模式的設計原則,但是表中存在重複欄位,如果對公用屬性部分進行修改則需要修改所有子類所對應表中的屬性值,映射的靈活性很大。另外對於子類的查詢只需要訪問單獨的表,對於父類的查詢需要檢索所有的表。
小結
通過上面三種方式優缺點的總結,再總結一下:
從複雜度的角度,方式1簡單(子類屬性不多);方式2主外鍵;方式3有重複欄位;
從查詢效能,方式1效率高;方式2需要表內串連或左外串連;方式3若查詢父類需要查詢所有類表;
從可維護性,方式1只需要修改一張表;方式2若某個屬性發生變化修改此類對應的表;方式3若父類屬性變化需要修改所有子類對應的表。
也就是說,當子類屬性不多時,優先選擇方式1,;子類屬性多,要求不嚴格時,優先選擇方式2。
看完後後,繼承映射是不是沒有那麼深奧了。三種方式聽起來很厲害,其實還是圍繞著我們之前所學過的主外鍵,第三張表,各種串連等。這些都是基礎。