双向 JPA OneToMany/ManyToOne 关联中的“关联的反面"是什么? [英] What is “the inverse side of the association” in a bidirectional JPA OneToMany/ManyToOne association?

查看:23
本文介绍了双向 JPA OneToMany/ManyToOne 关联中的“关联的反面"是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

@OneToMany<的示例部分/code> 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属性的解释中,是这样写的:

It seems to me that the Customer entity is the owner of the association. However, in the explanation for the mappedBy attribute in the same document, it is written that:

如果关系是双向的,然后在的反面(非拥有)与字段名称的关联或拥有关系的财产如例 1-60 所示.

if the relationship is bidirectional, then set the mappedBy element on the inverse (non-owning) side of the association to the name of the field or property that owns the relationship as Example 1-60 shows.

但是,如果我没记错的话,在示例中看起来,mappedBy 实际上是在关联的拥有方指定的,而不是在非拥有方指定的.

However, if I am not wrong, it looks like in the example, the mappedBy is actually specified on the owning side of the association, rather than the non-owning side.

所以我的问题基本上是:

So my question is basically:

  1. 在双向(一对多/多对一)关联中,哪个实体是所有者?我们如何指定一方为所有者?我们如何指定多方为所有者?

  1. In a bidirectional (one-to-many/many-to-one) association, which of the entities is the owner? How can we designate the One side as the owner? How can we designate the Many side as the owner?

关联的反面"是什么意思?我们如何将一侧指定为反面?我们如何将多边指定为逆?

What is meant by "the inverse side of the association"? How can we designate the One side as the inverse? How can we designate the Many side as the inverse?

推荐答案

要理解这一点,您必须退后一步.在 OO 中,客户拥有订单(订单是客户对象中的一个列表).没有客户就不可能有订单.所以客户似乎是订单的所有者.

To understand this, you must take a step back. In OO, the customer owns the orders (orders are a list in the customer object). There can't be an order without a customer. So the customer seems to be the owner of the orders.

但在 SQL 世界中,一项实际上将包含指向另一项的指针.由于 N 个订单有 1 个客户,因此每个订单都包含其所属客户的外键.这是连接",这意味着订单拥有"(或字面上包含)连接(信息).这与面向对象/模型世界完全相反.

But in the SQL world, one item will actually contain a pointer to the other. Since there is 1 customer for N orders, each order contains a foreign key to the customer it belongs to. This is the "connection" and this means the order "owns" (or literally contains) the connection (information). This is exactly the opposite from the OO/model world.

这可能有助于理解:

public class Customer {
     // This field doesn't exist in the database
     // It is simulated with a SQL query
     // "OO speak": Customer owns the orders
     private List<Order> orders;
}

public class Order {
     // This field actually exists in the DB
     // In a purely OO model, we could omit it
     // "DB speak": Order contains a foreign key to customer
     private Customer customer;
}

反面是对象的 OO所有者",在这种情况下是客户.客户在表中没有用于存储订单的列,因此您必须告诉它可以在订单表中保存此数据的位置(通过 mappedBy 发生).

The inverse side is the OO "owner" of the object, in this case the customer. The customer has no columns in the table to store the orders, so you must tell it where in the order table it can save this data (which happens via mappedBy).

另一个常见的例子是带有可以是父节点和子节点的节点的树.在这种情况下,两个字段在一个类中使用:

Another common example are trees with nodes which can be both parents and children. In this case, the two fields are used in one class:

public class Node {
    // Again, this is managed by Hibernate.
    // There is no matching column in the database.
    @OneToMany(cascade = CascadeType.ALL) // mappedBy is only necessary when there are two fields with the type "Node"
    private List<Node> children;

    // This field exists in the database.
    // For the OO model, it's not really necessary and in fact
    // some XML implementations omit it to save memory.
    // Of course, that limits your options to navigate the tree.
    @ManyToOne
    private Node parent;
}

这就解释了外键"多对一的设计作品.还有第二种方法,它使用另一个表来维护关系.这意味着,对于我们的第一个示例,您有三个表:一个包含客户的表、一个包含订单的表和一个包含主键对(customerPK、orderPK)的两列表.

This explains for the "foreign key" many-to-one design works. There is a second approach which uses another table to maintain the relations. That means, for our first example, you have three tables: The one with customers, the one with orders and a two-column table with pairs of primary keys (customerPK, orderPK).

这种方法比上面的方法更灵活(它可以轻松处理一对一、多对一、一对多甚至多对多).价格是那个

This approach is more flexible than the one above (it can easily handle one-to-one, many-to-one, one-to-many and even many-to-many). The price is that

  • 它有点慢(必须维护另一个表并且连接使用三个表而不是两个),
  • 连接语法更复杂(如果您必须手动编写许多查询,例如当您尝试调试某些内容时,这可能会很乏味)
  • 它更容易出错,因为当管理连接表的代码出现问题时,您可能会突然得到太多或太少的结果.

这就是我很少推荐这种方法的原因.

That's why I rarely recommend this approach.

这篇关于双向 JPA OneToMany/ManyToOne 关联中的“关联的反面"是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆