原來我們都是先設計http://www.jyygyx.com/db/在進行代碼編寫。也就是說都是先有http://www.jyygyx.com/db/,才有實體對象。但是這類開發思想其實不符合我們的面向對象思想。甚么是面向對象思想?面向對象是1種對現實世界了解和抽象的方法。通過面向對象方式,將現實世界的事物抽象成對象,現實世界中的關系抽象成類、繼承。
但是在關系型http://www.jyygyx.com/db/中的表與表之間的關系,并沒有繼承關系,不能說1張表繼承另外一張表,它們之間的關系只能是關聯,那末如何將這類繼承關系的表映照到我們的http://www.jyygyx.com/db/當中呢?Hibernate提供了3種基本實現策略。
例如:有以下表繼承結構體系:
1、 每棵類繼承樹基樹1張表
該種方案,是將不同的種類動物都放在同1張表。請看下面的繼承體系結構:
由于類繼承樹肯定是對應多個類,要把多個類的信息寄存在1張表中,必須有某種機制來辨別哪些記錄是屬于哪一個類的。這類機制就是,在表中添加1個字段,用這個字段的值來進行辨別。
注意:父類用普通的<class>標簽定義 ,在父類中定義1個discriminator,指定這個辨別字段的名稱和類型。子類用<subclass>標簽定義,其中name屬性是子類的全路徑名。
配置文件實現:
除非將父類定義成抽象的,否則父類也是1張表
這類策略使用joined-subclass 標簽來定義子類的 。父類、子類、每一個類都對應1張http://www.jyygyx.com/db/表。在父類對應的http://www.jyygyx.com/db/表中,實際上會存儲所有的記錄,包括父類和子類的記錄;在子類對應的http://www.jyygyx.com/db/表中,這個表只定義了子類中所獨有的屬性映照的字段。子類與父類,通過相同的主鍵值來關聯。
注意:
1.父類不再需要定義discriminator字段;
2.子類用<joined-subclass>標簽定義,其中name屬性是子類的全路徑名,需要包括1個key標簽,用來指定子類和父類之間是通過哪一個字段來關聯的。
3.Joined-subclass 標簽,既可以被class標簽所包括(表名了類之間的繼承關系),也能夠與class標簽所平行。當joined-subclass標簽的定義與class標簽平行的時候,需要在joined-subclass標簽中,添加extends屬性,里面的值是父類的全路徑名。
4.子類的其他屬性,像普通類1樣,定義在joined-subclass標簽的內部。
配置文件:
3、每一個具體子類1張表
這類策略是使用union-subclass標簽來定義子類的。每一個子類對應1張表,而且這個表的信息是完備的,即包括了所有從父類繼承下來的屬性映照字段。(joined-subclass定義的子類的表,只包括子類特有屬性映照字段)。
注意:
1. Union-subclass 標簽不再需要包括key標簽
2. Union-subclass標簽,既可以被class標簽所包括(這類包括關系正是表明子類間的繼承關系),也能夠與class標簽平行。當union-subclass標簽的 定義域class標簽平行的時候,需要在union-subclass標簽中,添加extends屬性,里面的值是父類的全路徑名稱。
3. 子類的其他屬性,像普通類1樣,定義在union-subclass標簽的內部。
配置文件:
總結:
Hibernate提供的這3種策略都可以實現表的繼承映照。在實際開發中具體使用何種策略,還需要我們進行權衡。例如策略1:效力好,就1張表,但是當表的數量增多時,會存在大量的冗余字段。策略2:層次清楚,沒有冗余。但是類的繼承層次越深,關聯的表越多。策略3:不能使用自增方案,由于自增,就有可能出現重復的主鍵,Hibernate的對象都是通過session來管理的,所以主鍵不能重復。
上一篇 水平三欄式布局