Hibernate實(shí)體層次設(shè)計(jì)(一)
Hibernate中支持3種類型的繼承形式:
1.Table per concrete class
表與子類之間的獨(dú)立一對(duì)一關(guān)系。
2.Table per subclass
每個(gè)子類對(duì)應(yīng)一張子表,并與主類共享主表。
3.Table per class hierarchy
表與類的一對(duì)多關(guān)系
3種方法的比較。
比較方面 |
Table per concrete class |
Table per subclass |
Table per class hierarchy |
關(guān)系數(shù)據(jù)模型的復(fù)雜度 | 缺點(diǎn):表中含有重復(fù)字段 |
缺點(diǎn):表的數(shù)目最多,并且表之間還有外鍵 參照關(guān)系 |
優(yōu)點(diǎn):只需要一個(gè)表 |
查詢性能 |
缺點(diǎn):查詢父類對(duì)象,也必須查詢所有具體的 子類對(duì)應(yīng)的表 |
缺點(diǎn):需要進(jìn)行表的內(nèi)連接或者左外連接 | 優(yōu)點(diǎn):無需表連接,查詢性能好 |
數(shù)據(jù)庫(kù)Schema的可維護(hù)性 | 缺點(diǎn):父類發(fā)生修改,必須修改所有子類的表 | 優(yōu)點(diǎn):某個(gè)類的屬性發(fā)生變化,只需修改和這個(gè)類對(duì)應(yīng)的表 | 優(yōu)點(diǎn):只需要修改一張表 |
是否支持多態(tài)查詢和關(guān)聯(lián) | 缺點(diǎn):不支持(實(shí)際上,是可以做到的,做法是指定完整的父類路徑,參見具體例子實(shí)現(xiàn)) | 優(yōu)點(diǎn):支持 | 優(yōu)點(diǎn):支持 |
是否符合關(guān)系數(shù)據(jù)模型的常規(guī)設(shè)計(jì) | 優(yōu)點(diǎn):符合 | 優(yōu)點(diǎn):符合 |
缺點(diǎn): 1)在表中,引入額外的區(qū)分子類的類型的字段 2)如果子類中的某個(gè)屬性不允許為null,在表中 無法為對(duì)應(yīng)的字段創(chuàng)建not null約束 |
配置文件說明 |
無需變化 |
使用joined-subclass節(jié)點(diǎn)來說明 |
使用discriminator節(jié)點(diǎn)來說明 |
下面,結(jié)合一個(gè)例子,分別討論。
對(duì)一個(gè)電子商務(wù)系統(tǒng)而言,不同的的貨物既有共性,也有各自不同的屬性。貨物都有廠商,名稱等屬性,而書籍有頁(yè)數(shù),DVD有分區(qū)屬性。在面向?qū)ο蟮某绦蛟O(shè)計(jì)中,我們通常將共性抽象為一個(gè)基類,而以不同的子類體現(xiàn)具體的特性。
共性歸為父類TItem,屬性如下:
id:Integer
factory:String
name:String
代表書籍的子類TBook,屬性如下:
pageCount:int
代表DVD的字類TDVD,屬性如下:
regionCode:String
這三個(gè)POJO類對(duì)應(yīng)的Java代碼如下:
父類TItem.java
package cn.blogjava.start;
import java.io.Serializable;
public class TItem implements Serializable {
private Integer id;
private String manufacturer;
private String name;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getManufacturer() {
return manufacturer;
}
public void setManufacturer(String manufacturer) {
this.manufacturer = manufacturer;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
import java.io.Serializable;
public class TItem implements Serializable {
private Integer id;
private String manufacturer;
private String name;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getManufacturer() {
return manufacturer;
}
public void setManufacturer(String manufacturer) {
this.manufacturer = manufacturer;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
子類TBook
package cn.blogjava.start;
import java.io.Serializable;
public class TBook extends TItem implements Serializable {
private int pageCount;
public int getPageCount() {
return pageCount;
}
public void setPageCount(int pageCount) {
this.pageCount = pageCount;
}
}
import java.io.Serializable;
public class TBook extends TItem implements Serializable {
private int pageCount;
public int getPageCount() {
return pageCount;
}
public void setPageCount(int pageCount) {
this.pageCount = pageCount;
}
}
子類TDVD
package cn.blogjava.start;
import java.io.Serializable;
public class TDVD extends TItem implements Serializable{
private String regionCode;
public String getRegionCode() {
return regionCode;
}
public void setRegionCode(String regionCode) {
this.regionCode = regionCode;
}
}
import java.io.Serializable;
public class TDVD extends TItem implements Serializable{
private String regionCode;
public String getRegionCode() {
return regionCode;
}
public void setRegionCode(String regionCode) {
this.regionCode = regionCode;
}
}
下面使用3種不同方式,一一實(shí)現(xiàn)。
posted on 2006-06-30 16:43 baim 閱讀(551) 評(píng)論(0) 編輯 收藏 所屬分類: 開源軟件框架