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

时间:2011-07-23 06:49:12

标签: java oop data-modeling

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

2 个答案:

答案 0 :(得分:2)

  

现在订单和订单商品存储在数据库中怎么办?订单是否仍然保留对集合的引用,或者仅提供一个简单的函数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会懒惰地获取集合,因此您需要了解一些其他概念,例如使用托管和分离实体来实际使其工作;您可能需要编写应用程序服务来完成合并分离的实体的工作,然后获取集合。

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

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

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

答案 1 :(得分:1)

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

只有当您需要访问订单商品(搜索LAZY LOADING)而不是每次从DB加载订单实体时,才应执行此查询。

在Order模型类中使用对OrderItem集合的引用将利用您的应用程序,以防您需要访问同一请求 - 响应流中的两个订单项。

getOrderItems()方法的框架将是这样的:

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