Java 使用@OneToMany和@ManyToMany的区别

Java 使用@OneToMany和@ManyToMany的区别,java,jakarta-ee,jpa,Java,Jakarta Ee,Jpa,我很难理解@OneToMany和@ManyToMany之间的区别。当我使用@OneToMany时,它默认创建一个JoinTable,如果添加mappedBy属性,两个实体之间将具有双向关系 我有一个问题可能属于许多类别,一个类别可能属于许多问题。我不明白我应该使用@manytomy还是@OneToMany,因为对我来说,这似乎完全是一回事,但可能不是 有人能解释一下吗?@许多关系的两侧都有相互引用的外键。有时,这种关系由相邻的表进行调解 @一对一的关系有一个外键在“一”面,而不是在“多”面。在@

我很难理解
@OneToMany
@ManyToMany
之间的区别。当我使用
@OneToMany
时,它默认创建一个JoinTable,如果添加mappedBy属性,两个实体之间将具有双向关系

我有一个
问题
可能属于许多
类别
,一个
类别
可能属于许多
问题
。我不明白我应该使用
@manytomy
还是
@OneToMany
,因为对我来说,这似乎完全是一回事,但可能不是


有人能解释一下吗?

@许多关系的两侧都有相互引用的外键。有时,这种关系由相邻的表进行调解

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


记住@manytomy双向关系不需要对称

嗯,区别在于您试图使用对象反映的设计

在您的情况下,每个
问题
都可以分配到多个
类别
——因此这是
@*与许多
关系的标志。现在,您必须决定是否:

  • 每个
    类别
    只能分配一个
    问题
    (这将导致唯一约束,这意味着没有其他类别可以引用相同的问题)-这将是
    @OneToMany
    关系
  • 每个
    类别
    可以分配多个
    问题
    (在
    类别
    表中没有唯一约束)-这将是
    @manytomy
    关系
@OneToMany(问题->类别)

只有当您使用
@JoinTable
明确定义了连接表,或者当它是一个单向的关系,其中拥有方是“一”方时,此关系才能由连接表表示(这意味着在
问题
实体中,您拥有
类别
的集合,但在
类别
中,您没有对
问题
的任何引用)

仔细想想,使用联接表似乎很合理。DBMS没有其他方法可以将
Question
表中的一行与
Categories
表中的多行保存连接

但是,如果要对双向关系进行建模,则需要指定
类别('Many'侧)是关系的拥有方。在这种情况下,DBMS可以在
类别
表中使用外键创建联接列,因为每个
类别
行只能与一个
问题
连接

通过这种方式,您没有任何联接表,只有简单的外键(尽管如此,正如前面所指出的,您仍然可以使用
@JoinTable
)强制创建联接表)

@ManyToMany


此关系必须表示为联接表。它的工作原理基本上与单向的
@OneToMany
关系非常相似,但在这种情况下,您可能会将
问题
中的多行与
类别

中的多行联接在一起。在您的问题和类别案例中,您应该使用@ManyToMany关系。@ManyToMany基本上表示“一个问题可以同时属于多个类别”和“一个类别可以同时包含多个问题”。将自动创建一个新表来存储映射。您的代码如下所示:

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

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

@Entity
public class Category implements Serializable {
    ...
    @OneToMany(mappedBy="theCategory")
    private List<Question> questions;
    ...
}
@实体
公共类问题实现了可序列化{
...
@许多
私人名单类别;
...
}
@实体
公共类类别实现可序列化{
...
@许多
私人名单问题;
...
}
如果您对问题和类别使用@OneToMany关系(假设一边是类别,另一边是问题),这意味着“一个问题只能属于一个类别”和“一个类别可以同时包含多个问题”。不需要新表来存储映射。相反,将在多个端自动创建一个新字段来记录一个端的ID。您的代码如下所示:

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

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

@Entity
public class Category implements Serializable {
    ...
    @OneToMany(mappedBy="theCategory")
    private List<Question> questions;
    ...
}
@实体
公共类问题实现了可序列化{
...
@许多酮
私有范畴;
...
}
@实体
公共类类别实现可序列化{
...
@OneToMany(mappedBy=“theCategory”)
私人名单问题;
...
}

精彩的解释。应该有更多的投票权。