在 @OneToMany
JPA 注释参考 的示例部分:
示例 1-59 @OneToMany - 使用泛型的客户类
@Entity
public class Customer implements Serializable {
...
@OneToMany(cascade=ALL, mappedBy="customer")
public Set<Order> getOrders() {
return orders;
}
...
}
示例 1-60 @ManyToOne - 使用泛型的订单类
@Entity
public class Order implements Serializable {
...
@ManyToOne
@JoinColumn(name="CUST_ID", nullable=false)
public Customer getCustomer() {
return customer;
}
...
}
在我看来 Customer
实体是协会的所有者。但是,在同一文档中对 mappedBy
属性的解释中,写道:
如果关系是双向的,则将关联的反向(非拥有)端的 mappedBy 元素设置为拥有该关系的字段或属性的名称,如示例 1-60 所示。
但是,如果我没记错的话,示例中的 mappedBy
实际上是在关联的拥有方而不是非拥有方指定的。
所以我的问题基本上是:
在双向(一对多/多对一)关联中,哪个实体是所有者?我们如何指定一方为拥有者?我们如何指定多方为所有者?
“协会的反面”是什么意思?我们怎么能把单边指定为反面呢?我们如何将多面指定为逆面?
原文由 Behrang 发布,翻译遵循 CC BY-SA 4.0 许可协议
要理解这一点,您必须退后一步。在 OO 中,客户拥有订单(订单是客户对象中的列表)。没有客户就没有订单。所以客户似乎是订单的所有者。
但在 SQL 世界中,一项实际上包含指向另一项的指针。由于 N 个订单有 1 个客户,每个订单都包含一个指向其所属客户的外键。这就是“连接”,这意味着订单“拥有”(或字面上包含)连接(信息)。这与 OO/模型世界完全相反。
这可能有助于理解:
反面是对象的 OO“所有者”,在本例中是客户。客户在表中没有用于存储订单的列,因此您必须告诉它可以在订单表中的哪个位置保存此数据(通过
mappedBy
发生)。另一个常见的例子是树的节点既可以是父母也可以是孩子。在这种情况下,两个字段在一个类中使用:
这解释了为“外键”设计的多对一工作原理。还有第二种方法,它使用另一个表来维护关系。这意味着,对于我们的第一个示例,您有三个表:一个包含客户的表,一个包含订单的表和一个包含主键对(customerPK、orderPK)的两列表。
这种方式比上面的方式更灵活(可以轻松处理一对一、多对一、一对多甚至多对多)。价格是
这就是为什么我很少推荐这种方法。