2011-11-19 68 views
7

我在理解@OneToMany@ManyToMany之間的區別時遇到了一些問題。當我使用@OneToMany時,它默認創建一個JoinTable,如果你添加了mappedBy屬性,你將在兩個實體之間建立雙向關係。使用@OneToMany和@ManyToMany之間的區別

我有一個Question可能屬於許多Categories,並且一個Category可能屬於許多Questions。我不明白我是否應該使用@ManyToMany@OneToMany,因爲對我來說它看起來完全一樣,但它可能不是。

有人能解釋嗎?

回答

15

嗯,不同之處在於您嘗試使用對象反映的設計。

在你的情況下,每個Question可以分配到多個Categories - 所以這是一個@*ToMany關係的標誌。現在,你必須決定是否:

  • 每個Category只能有一個Question分配給它(這將導致獨特約束,這意味着沒有其他的分類可參照同樣的問題) - 這將是@OneToMany的關係,
  • 每個Category可以有多個Questions分配給它(在Category表中將沒有唯一約束) - 這將是@ManyToMany的關係。

@OneToMany(問題 - >類)

這種關係可以通過連接表只有當你明確地定義,以便使用@JoinTable或表示當它是一個單向關係,其中擁有方是「一方」(這意味着在Question實體中您有一個Categories的集合,但在Categories中,您沒有任何對Question的引用)。

如果你考慮一下,使用連接表看起來相當合理。 DBMS沒有其他方式可以將Question表中的一行與Categories表中的多行保存連接。

但是,如果您想建立雙向關係模型,則需要指定Category('多邊')是關係的主角。在這種情況下,DBMS可以在Category表中使用外鍵創建連接列,因爲每個Category行只能連接一個Question

通過這種方式,您不需要任何連接表,只需使用簡單的外鍵(仍然可以像開頭指出的那樣,使用@JoinTable強制創建連接表)。

@ManyToMany

這種關係必須被表示爲連接表。它基本上與單向@OneToMany關係非常相似,但在這種情況下,您可能會有多行從Question連接到Categories的多行。

+0

非常好的解釋。應該有更多的upvotes。 – LppEdd

0

@ManyToMany關係在關係的兩邊都有相互引用的外鍵。有時候,這種關係是由相鄰的桌子來調節的。

@OneToMany關係在「一邊」有一個外鍵,而不在「多」一邊。在@OneToMany關係中,一個對象是「父母」,一個是「孩子」。父母控制着孩子的存在。

請記住@ManyToMany雙向關係不需要是對稱的!

0

在您的問題&類別案例中,您應該使用@ManyToMany關係。 @ManyToMany基本上意味着「一個問題可以同時屬於多個類別」和「一個類別可以同時包含很多問題」。將自動創建一個新表來存儲映射。您的代碼應該是這樣的:

@Entity 
public class Question implements Serializable { 
    ... 
    @ManyToMany 
    private List<Category> categories; 
    ... 
} 

@Entity 
public class Category implements Serializable { 
    ... 
    @ManyToMany 
    private List<Question> questions; 
    ... 
} 

如果您使用您的問題和分類@OneToMany關係(假設爲一方和其他問題類別),這意味着「一個問題只能屬於一個類別「和」一個類別可以同時包含很多問題「。不需要新的表格來存儲映射。而是在許多方面自動創建一個新的字段來記錄一方的ID。你的代碼看起來像這樣:

@Entity 
public class Question implements Serializable { 
    ... 
    @ManyToOne 
    private Category theCategory; 
    ... 
} 

@Entity 
public class Category implements Serializable { 
    ... 
    @OneToMany(mappedBy="theCategory") 
    private List<Question> questions; 
    ... 
}