使用@OneToMany和@ManyToMany之间的区别
我在理解@OneToMany
和@ManyToMany
之间的区别时遇到了一些麻烦。 当我使用@OneToMany
它默认创建一个JoinTable,如果你添加mappedBy属性,你将在两个实体之间有双向关系。
我有一个可能属于许多Categories
,一个Category
可能属于许多Questions
。 我不明白我是否应该使用@ManyToMany
或@OneToMany
因为对我而言似乎完全相同,但它可能不是。
有人可以解释一下吗?
嗯,不同之处在于您尝试使用对象进行反映的设计。
在您的情况下,每个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
多行。
@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; ... }