Hibernate/JPA ManyToOne vs OneTomany

我现在正在阅读 Hibernate 关于 实体协会的文档,我遇到了一些困难,想弄清楚一些事情。它在本质上与 ManyToOneOneToMany关联之间的差异有关。虽然我在实际的项目中使用过它们,但是我不能完全理解它们之间的区别。根据我的理解,如果一个表/一个实体与另一个实体有 ManyToOne关联,那么这个关联应该来自另一个 OneToMany。那么,我们应该如何根据特定的情况来决定选择哪一个,以及它如何影响数据库/查询/结果?到处都有这样的例子吗?

附注: 我认为这将是有益的,因为它的相关性的问题,如果有人除了解释是什么点的所有者的协会和双向和单向协会之间的区别。

40807 次浏览

假设您有一个 Order 和一个 OrderLine。您可以选择在 Order 和 OrderLine 之间使用单向 OneTomany (Order 将包含 OrderLines 的集合)。或者可以选择在 OrderLine 和 Order 之间建立 ManyToOne 关联(OrderLine 将引用其 Order)。或者您可以选择同时拥有这两个关联,在这种情况下,关联将成为双向的 OneTomany/ManyToOne 关联。

您选择的解决方案主要取决于情况以及实体之间的耦合程度。例如,如果一个用户、一家公司、一个提供商都有许多地址,那么在每个地址和 Address 之间使用单向地址是有意义的,而且 Address 不知道它们的所有者。

假设您有一个 User 和一个 Message,其中一个用户可以拥有数千条消息,将其建模为 ManyToOne from Message to User 是有意义的,因为您很少会询问一个用户的所有消息。不过,关联可以是双向的,只是为了帮助处理查询,因为 JPQL 查询通过导航实体之间的关联来连接实体。

在双向关联中,您可能处于对象图不一致的情况中。例如,Order A 将有一个 OrderLines 的空集,但是一些 OrderLines 将有一个对 Order A 的引用,JPA 强加的总是将关联的一侧作为所有者端,另一侧作为反向端。反面被 JPA 忽略。所有者一方是决定什么关系存在的一方。在一对多双向关联中,所有者方必须是多方。因此,在前面的示例中,所有者端将是 OrderLine,而 JPA 将持久化行和订单 A 之间的关联,因为这些行有对 A 的引用。

这样一种联系将如下图所示:

顺序:

@OneToMany(mappedBy = "parentOrder") // mappedBy indicates that this side is the
// inverse side, and that the mapping is defined by the attribute parentOrder
// at the other side of the association.
private Set<OrderLine> lines;

排序:

@ManyToOne
private Order parentOrder;

另外,在保存关联时,使用 @ManytoOne端作为所有者只需要 n + 1个查询。其中 n 是关联的数目(许多边)。

而将 @OneToMany作为所有者,同时插入具有关联(许多边)的父实体(一边)将导致2 * N + 1个查询。其中一个查询用于插入关联,另一个查询用于更新关联实体中的外键。

我会举个例子来回答。假设您有一个订购或 POS 系统的设计。然后,每个订单都有订单细节(例如产品)。在这种情况下,我们有一个 @oneToMany关系。同样适用于销售和销售细节的关系。

如果我有一个用户表,每个用户绑定到一个特定的商店,那么我们可以有许多用户绑定到同一个商店,因此 @manyToOne

虽然上面的答案是准确的,但我将以不同的方式给出答案。

@OneToMany@ManyToOne都有两个部分: 左部分和右部分。例如:

  • @OneToMany = ‘ One’是左半部分,‘ Many’是右半部分
  • @ManyToOne = ‘ Many’是左半部分,‘ One’是右半部分

使用这种理解的简单关联规则是,左边部分表示您在其中定义关联的类。

因此,如果在 OrderLine 类中定义引用 Order 类的 @ManyToOne,则表示与一个 Order 类关联的许多 OrderLine。