关于数据建模的非常基本的问题
假设我必须用 Java 为 Order
开发一个简单的数据模型,其中包含 Order Items
。看起来 Order
应该保存对集合 Order Items
的引用 现在如果存储 Order
和 Order 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这取决于持久层如何使用对象模型将类映射到数据库表。如果您使用 Hibernate/JPA/EclipseLink/Toplink 或类似的 ORM 框架,您只需在
Order
类中有一个 getter 方法,该方法将返回OrderItem
实例的集合。部分代码表示为:我没有列出框架使用的所有注释,包括每个实体类的键,但您需要这样做才能使事情正常工作。然而,要点是:
Order
类的每个实例都包含 Id,它可能是自然键(也可能是生成的键)。getOrderItems
方法将导致返回与订单关联的订单项的Set
。请注意,大多数 ORM 都会延迟获取集合,因此您需要了解更多概念,例如使用托管实体和分离实体才能真正发挥作用;您可能需要编写一个应用程序服务来完成合并分离实体的工作,然后获取集合。其中一条评论指出,无需从
OrderItem
类引用Order
。这将导致单向关系而不是双向关系。您可以在大多数 ORM 框架中使用单向关系,但请考虑以下事项:OrderItem
引用Order
,而无需您做任何进一步的努力,而其他 ORM 框架可能要求您使用 Join 表。如果您要在数据库中保存对象图,则必须知道哪个OrderItem
映射到Order
;通过从OrderItem
中删除引用,您将被迫将此信息映射到其他地方、不同的实体中,并且通常会生成不同的表;这就是前面提到的连接表。Order
负责访问OrderItem
实例,那么您不需要双向关系。但是,如果您发现自己需要访问OrderItem
的Order
,那么您将需要双向关系。我建议阅读相互注册模式,以便在这种情况下,无论对Order
或OrderItem
类执行任何突变操作,您始终能够保持引用完整性。如果没有这种模式,您几乎总是会发现自己看到模糊的、无法解释的和不正确的对象图,从而导致数据库状态不一致。如果您没有使用 ORM 或者您不打算使用,那么这取决于您正在访问
OrderItem
实例;简而言之,这取决于您如何编写持久层。如果您使用 DAO 模式,那么在 DAO 接口中添加一个新方法retrieveItemsByOrderId
就是解决方案。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 ofOrderItem
instances. Partial code representation would be: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:
Order
class contains the Id, which may be the natural key (or may be a generated one).getOrderItems
method will result in theSet
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 theOrderItem
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:Order
fromOrderItem
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 whichOrderItem
maps to anOrder
; by removing the reference from theOrderItem
, 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.Order
is responsible for accessingOrderItem
instances, then you do not need bidirectional relationships. But if you find yourself needing to access theOrder
for anOrderItem
, 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 onOrder
orOrderItem
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 methodretrieveItemsByOrderId
into your DAO interface would be the solution.我认为您应该在 Order 模型类中保留对 OrderItem 集合的引用。然后,您可以实现 getOrderItems() 方法,该方法根据订单 ID 从数据库中检索项目。
仅当您需要访问订单项(搜索 LAZY LOADING)时才应执行此查询,而不是每次从数据库加载订单实体时执行此查询。
如果您需要在同一请求响应流中访问两倍的订单项,则在 Order 模型类中使用对 OrderItem 集合的引用将充分利用您的应用程序。
getOrderItems() 方法的骨架如下所示:
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: