关于数据建模的非常基本的问题

发布于 2024-11-25 19:07:41 字数 287 浏览 0 评论 0原文

假设我必须用 Java 为 Order 开发一个简单的数据模型,其中包含 Order Items。看起来 Order 应该保存对集合 Order Items 的引用 现在如果存储 OrderOrder Items 会怎样在数据库中? Order 是否仍保留对集合的引用,还是应该提供一个简单的函数 retrieveItemsByOrderId

Suppose I have to develop a simple data model in Java for Order, which contains Order Items. It looks like Order should hold a reference to a collection Order Items Now what if Order and Order Items are stored in a database? Should the Order still hold a reference to the collection or just a simple function retrieveItemsByOrderId should be provided instead?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

撩人痒 2024-12-02 19:07:41

现在,如果订单和订单项目存储在数据库中会怎样? Order 是否仍应保留对集合的引用,还是应提供一个简单的函数retrieveItemsByOrderId?

这取决于持久层如何使用对象模型将类映射到数据库表。如果您使用 Hibernate/JPA/EclipseLink/Toplink 或类似的 ORM 框架,您只需在 Order 类中有一个 getter 方法,该方法将返回 OrderItem 实例的集合。部分代码表示为:

class Order
{

    private long id;
    private Set<OrderItem> orderItems;
    ...
    public Set<OrderItem> getOrderItems()
    {
        return orderItems;
    }

    public void setOrderItems(Set<OrderItem> orderItems)
    {
        this.orderItems = orderItems;
    }
}

class OrderItem
{
    private Order order;
    ...
    public Order getOrder()
    {
        return order;
    }

    public void setOrder(Order order)
    {
        this.order = order;
    }
}

我没有列出框架使用的所有注释,包括每个实体类的键,但您需要这样做才能使事情正常工作。然而,要点是:

  • Order 类的每个实例都包含 Id,它可能是自然键(也可能是生成的键)。
  • 调用 getOrderItems 方法将导致返回与订单关联的订单项的 Set。请注意,大多数 ORM 都会延迟获取集合,因此您需要了解更多概念,例如使用托管实体和分离实体才能真正发挥作用;您可能需要编写一个应用程序服务来完成合并分离实体的工作,然后获取集合。

其中一条评论指出,无需从 OrderItem 类引用 Order。这将导致单向关系而不是双向关系。您可以在大多数 ORM 框架中使用单向关系,但请考虑以下事项:

  • 维护单向关系的引用完整性(使用外键)并非易事;这取决于您的 ORM 框架。某些 ORM 框架可能允许您无需从 OrderItem 引用 Order,而无需您做任何进一步的努力,而其他 ORM 框架可能要求您使用 Join 表。如果您要在数据库中保存对象图,则必须知道哪个 OrderItem 映射到 Order;通过从 OrderItem 中删除引用,您将被迫将此信息映射到其他地方、不同的实体中,并且通常会生成不同的表;这就是前面提到的连接表。
  • 单向关系足以满足大多数用途。如果 Order 负责访问 OrderItem 实例,那么您不需要双向关系。但是,如果您发现自己需要访问 OrderItemOrder,那么您将需要双向关系。我建议阅读相互注册模式,以便在这种情况下,无论对 OrderOrderItem 类执行任何突变操作,您始终能够保持引用完整性。如果没有这种模式,您几乎总是会发现自己看到模糊的、无法解释的和不正确的对象图,从而导致数据库状态不一致。

如果您没有使用 ORM 或者您不打算使用,那么这取决于您正在访问 OrderItem 实例;简而言之,这取决于您如何编写持久层。如果您使用 DAO 模式,那么在 DAO 接口中添加一个新方法 retrieveItemsByOrderId 就是解决方案。

Now what if Order and Order Items are stored in a database? Should the Order still hold a reference to the collection or just a simple function retrieveItemsByOrderId should be provided instead?

This would depend on how your object model is used by the persistence layer to map classes to the database tables. If you are using Hibernate/JPA/EclipseLink/Toplink or a similar ORM framework, you would merely have a getter method in your Order class that would return the collection of OrderItem instances. Partial code representation would be:

class Order
{

    private long id;
    private Set<OrderItem> orderItems;
    ...
    public Set<OrderItem> getOrderItems()
    {
        return orderItems;
    }

    public void setOrderItems(Set<OrderItem> orderItems)
    {
        this.orderItems = orderItems;
    }
}

class OrderItem
{
    private Order order;
    ...
    public Order getOrder()
    {
        return order;
    }

    public void setOrder(Order order)
    {
        this.order = order;
    }
}

I haven't listed all annotations in use by the frameworks, including the keys for each entity class, but you'll need to do this to get things working. The salient points however are:

  • each instance of an Order class contains the Id, which may be the natural key (or may be a generated one).
  • invoking the getOrderItems method will result in the Set of order items associated with an order to be returned. Note that most ORMs will lazily fetch collections, so you'll need to understand a few more concepts like working with managed and detached entities to actually get this to work; you might need to write an application service to do the work of merging detached entities and then fetch the collection.

One of the comments stated that there is no need to reference the Order from the OrderItem class. This would lead to a unidirectional relationship instead of a bidirectional one. You can use unidirectional relationships in most ORM frameworks, but consider the following:

  • It would not be trivial to maintain referential integrity (using foreign keys) for unidirectional relationships; this would depend on your ORM framework. Some ORM frameworks might allow you to not have a reference to Order from OrderItem without any further effort on your part, while others might require you to use a Join table. If you are persisting an object graph in the database, then it is imperative to know which OrderItem maps to an Order; by removing the reference from the OrderItem, you will be forced to map this information elsewhere, in a different entity and usually resulting in a different table; this is the Join table that are referred to previously.
  • Unidirectional relationships are sufficient for most uses. If the Order is responsible for accessing OrderItem instances, then you do not need bidirectional relationships. But if you find yourself needing to access the Order for an OrderItem, then you will need a bidirectional relationship. I would suggest reading the Mutual Registration Pattern, so that you will always be able to maintain referential integrity irrespective of any mutation operations performed on Order or OrderItem classes in such a case. Without that pattern, you are almost always going to find yourself seeing vague, unexplained and incorrect object graphs resulting in an inconsistent database state.

If you are not using ORM or you don't intend to, then it would depend on you are accessing the OrderItem instances; in short, it depends on how you are writing your persistence layer. If you are using the DAO pattern, then adding a new method retrieveItemsByOrderId into your DAO interface would be the solution.

表情可笑 2024-12-02 19:07:41

我认为您应该在 Order 模型类中保留对 OrderItem 集合的引用。然后,您可以实现 getOrderItems() 方法,该方法根据订单 ID 从数据库中检索项目。

仅当您需要访问订单项(搜索 LAZY LOADING)时才应执行此查询,而不是每次从数据库加载订单实体时执行此查询。

如果您需要在同一请求响应流中访问两倍的订单项,则在 Order 模型类中使用对 OrderItem 集合的引用将充分利用您的应用程序。

getOrderItems() 方法的骨架如下所示:

public List<OrderItem> getOrderItems(){
    if(this.orderItems==null)
        // perform the query
        // set the this.orderItems values
    }
    return this.orderItems
}

I think you should keep a reference to OrderItem collection in your Order model class. Then, you could implement the method getOrderItems() that retrieves the items from the db based on the order id.

This query should be performed only if you need to access the order items (search for LAZY LOADING) and not every time you load the Order entity from DB.

Using a reference to OrderItem collection in your Order model class will leverage your application in case you need to access twice the order items in the same request-response flow.

A skeleton of getOrderItems() method would be like this:

public List<OrderItem> getOrderItems(){
    if(this.orderItems==null)
        // perform the query
        // set the this.orderItems values
    }
    return this.orderItems
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文