2011-10-05 22 views
0

考慮下面的例子:JPA - 一個與多個表之間共享主密鑰的一種關係

我有3個表:水果,橙和蘋果果表中生成

ID和是主鍵這裏

ID也是Orange和蘋果(共享主鍵)

所以對於如主鍵如果水果中的id是1,2,3,4,5 - 那麼場景可能是1,2,橙色,3,4是蘋果,而5又是橙色。

所以橙色表格會有id 1, 2,5而蘋果表將有id爲3,4

=================================== 
Fruit 
=================================== 
id  | shape 
=================================== 
    1  | round 
    2  | round 
    3  | oblong 
    4  | oblong 
    5  | round 
=================================== 


=================================== 
Orange 
=================================== 
id  | color | taste 
=================================== 
    1  | orange | sour 
    2  | orange | sour 
    5  | orange | sour 
=================================== 


=================================== 
Apple 
=================================== 
id  | density | weight 
=================================== 
    1  | hard  | 200 
    2  | hard  | 220 
    5  | hard  | 230 
=================================== 

問題:如何創建實體類捕獲relationshipd也只有JPA註解(我不想使用Hibernate generatedValue註釋)。

如果這樣的註釋是可能的純JPA然後請指導我。

的Nik

+0

它看起來,你想要做的是繼承(橙延伸水果和蘋果 - >水果)。你有沒有評估過這個選項? –

+0

這只是一個假設的例子。和不。沒有繼承關係。它更像僱員<->地址關係。每個員工將有一個地址,每個地址將只映射到一個員工。員工和地址的主鍵是共享的。 Means Employee_Id(這是Employee的主鍵)也是Address作爲外鍵的主鍵。 – Nik

回答

0

爲了通過迫使兩個Java字段(ID和關聯)來映射在同一列上進行測試。

例如,

class Orange { 

    @Id 
    @Column(name="id") 
    long id; 


    @OneToOne 
    @JoinColumn(name="id") 
    Fruit fruit; 

    public Orange(Fruit fruit) { 
     this.fruit = fruit; 
     this.id = fruit.id; 
    } 

    protected Orange() { } // default constructor required by JPA 
} 

但我不知道JPA提供者將如何表現。

2

您的情況看起來像設計模式的一個實例,稱爲「泛化專業化」(簡稱Gen-Spec)。如何使用數據庫表建模gen-spec的問題始終在SO中出現。

如果您在OOPL(如Java)中對gen-spec進行建模,則可以使用子類繼承功能來爲您處理細節。您只需定義一個類來處理泛化對象,然後定義一個子類集合,每個專用對象類型都有一個。每個子類都會擴展廣義類。這很簡單直接。

不幸的是,據我所知,關係數據模型沒有內置子類繼承,而SQL數據庫系統不提供任何這樣的設施。但你並沒有失敗。您可以設計您的表格以與OOP的類結構相似的方式對gen-spec進行建模。當新項目添加到廣義類時,您必須安排實現自己的繼承機制。詳情如下。

類結構相當簡單,一個表爲gen類,一個表爲每個spec子類。這是來自Martin Fowler網站的一個很好的例子。 Class Table Inheritance。請注意,在該圖中,Cricketer既是一個子類又是一個超類。你必須選擇哪些屬性放在哪個表中。該圖顯示了每個表中的一個示例屬性。

棘手的細節是如何爲這些表定義主鍵。 gen類表以通常的方式得到一個主鍵(除非這個表是另一個泛化的特殊化,比如Cricketers)。大多數設計師給主鍵一個標準名稱,如「Id」。他們使用自動編號功能來填充Id字段。 spec類表獲得一個主鍵,可以命名爲「Id」,但不使用自動編號功能。相反,每個子類表的主鍵都被約束爲引用廣義表的主鍵。這使得每個專用主鍵都是外鍵以及主鍵。請注意,對於板球運動員來說,身份證字段將引用玩家中的身份證字段,但身邊的身份證字段將引用玩家身份證號碼中的身份字段。

現在,當您添加新項目時,您必須保持參照完整性,以下是方法。
您首先在gen表中插入新行,爲除主鍵以外的所有屬性提供數據。自動編號機制生成一個唯一的主鍵。接下來,將一個新行插入到適當的規範表中,包括其所有屬性(包括主鍵)的數據。您使用的主鍵是剛生成的全新主鍵的副本。主鍵的傳播可以稱爲「窮人的繼承」。

現在,當您希望所有通用數據與來自一個子類的所有專用數據一起使用時,只需通過公用密鑰將兩個表連接起來即可。所有與該子類無關的數據將退出該連接。它光滑,簡單,快速。

實現gen-spec模式的SQL表的設計可能有點棘手。數據庫設計教程常常掩蓋了這個主題。但它在實踐中一次又一次地出現。

如果您在「泛化專業化關係建模」上搜索網頁,您會發現幾篇有用的文章,教您如何做到這一點。在這個論壇中,你也會被指出幾次這個話題。

這篇文章通常會向您展示如何設計一個表來捕獲所有通用數據和每個子類的一個專用表,這些表將包含特定於該子類的所有數據。有趣的部分涉及子類表的主鍵。您不會使用DBMS的自動編號功能來填充子類主鍵。相反,您將編寫應用程序以將通用表中獲得的主鍵值傳播到適當的子類表中。

這在廣義數據和專用數據之間建立了雙向關聯。每個專門的子類的簡單視圖將一起收集廣義和專門的數據。一旦你掌握了它,它很容易,它表現相當好。

相關問題