假设我必须在Java中为Order
开发一个包含Order Items
的简单数据模型。看起来Order
应该包含对集合的引用Order Items
现在如果Order
和Order Items
存储在数据库中会怎么样?如果Order
仍然保留对集合的引用,或者只应提供一个简单的函数retrieveItemsByOrderId
吗?
答案 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框架中使用单向关系,但请考虑以下事项:
Order
引用OrderItem
,而其他框架可能要求您使用Join表。如果要在数据库中持久保存对象图,则必须知道哪个OrderItem
映射到Order
;通过从OrderItem
中删除引用,您将被迫将此信息映射到其他位置,在不同的实体中,并且通常会生成不同的表;这是之前提到的Join表。Order
负责访问OrderItem
个实例,那么您不需要双向关系。但是,如果您发现自己需要访问Order
OrderItem
,那么您将需要双向关系。我建议阅读Mutual Registration Pattern,以便在这种情况下,无论在Order
或OrderItem
类上执行任何变异操作,您始终都能够保持参照完整性。如果没有这种模式,您几乎总会发现自己看到模糊,无法解释和不正确的对象图,导致数据库状态不一致。如果您没有使用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
}