使用@OneToMany和@ManyToMany之间的区别

我在理解@OneToMany@ManyToMany之间的区别时遇到了一些麻烦。 当我使用@OneToMany它默认创建一个JoinTable,如果你添加mappedBy属性,你将在两个实体之间有双向关系。

我有一个可能属于许多Categories ,一个Category可能属于许多Questions 。 我不明白我是否应该使用@ManyToMany@OneToMany因为对我而言似乎完全相同,但它可能不是。

有人可以解释一下吗?

嗯,不同之处在于您尝试使用对象进行反映的设计。

在您的情况下,每个Question都可以分配到多个Categories – 这是@*ToMany关系的标志。 现在你必须决定是否:

  • 每个Category只能分配一个Question (它将产生一个唯一约束,这意味着没有其他类别可以引用同一个问题 ) – 这将是@OneToMany关系,
  • 每个Category可以分配多个QuestionsCategory表中没有唯一约束) – 这将是@ManyToMany关系。

@OneToMany(问题 – >类别)

只有当你使用@JoinTable明确定义或者它是一个单向关系时,这种关系可以用连接表来表示,其中拥有方是’一方’(这意味着在Question实体中你有一个Categories的集合,但在Categories您没有任何对该Question引用)。

如果你考虑一下,使用连接表似乎是合理的。 没有其他方法DBMS可以在Question表中的一行与Categories表中的多行之间保存连接。

但是,如果要建模双向关系,则需要指定Category (“许多”方)是关系的拥有方。 在这种情况下,DBMS可以在Category表中创建带有外键的连接列,因为每个Category行只能与一个Question连接。

通过这种方式,您没有任何连接表,只有简单的外键(仍然如开头一样,您可以强制使用@JoinTable创建连接表)。

@ManyToMany

此关系必须表示为连接表。 它基本上与单向@OneToMany关系非常相似,但在这种情况下,您可能有多个来自Question行,其中包含来自Categories多行。

@ManyToMany关系在关系的两边都有相互引用的外键。 有时,这种关系是由相邻的表调解的。

@OneToMany关系在“一”方面有一个外键,而在“很多”方面没有。 在@OneToMany关系中,一个对象是“父”,一个是“子”。 父母控制孩子的存在。

请记住,@ ManyToMany双向关系不需要是对称的!

在您的问题和类别案例中,您应该使用@ManyToMany关系。 @ManyToMany基本上意味着“一个问题可以同时属于许多类别”和“一个类别可以同时包含许多问题”。 将自动创建一个新表来存储映射。 你的代码看起来像这样:

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

如果您对问题和类别使用@OneToMany关系(比如说一方面的类别和另一方面的问题),这意味着“一个问题只能属于一个类别”,“一个类别可以同时包含许多问题”时间”。 存储映射不需要新表。 相反,将在Many侧自动创建一个新字段以记录One侧的ID。 你的代码看起来像这样:

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