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

问题描述:

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

我有一个Question可能属于许多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的多行。

+0

非常好的解释。应该有更多的upvotes。 – LppEdd

@ManyToMany关系在关系的两边都有相互引用的外键。有时候,这种关系是由相邻的桌子来调节的。

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

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

在您的问题&类别案例中,您应该使用@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; 
    ... 
}