为 ORM 域图设计 JPARepository(ies) 的最佳实践



我一直在使用标准MVC架构(如域层(作为POJO和存储库来设计Spring rest API,以从数据库表中获取域数据。到目前为止,这些实体是隔离的,因此设计充当每个实体的单独 RestController、服务和存储库流。 我一直在寻求了解域对象(即 ORM(中关联的最佳实践。 例如,让我们以以下伪代码来说明域类(仅用于表达所讨论的设计。我没有提供完整的课程(:

public class Customer {
@Column
private int id;
@Column;
private String name;
@OneToMany
private List<Order> orders;
//...getters setters
}
public class Order {
@Column
private int id;
@Column;
private String orderNumber;
@OneToMany
private List<Product> products;
@ManyToOne
private Customer customer;
//...getters setters
}
public class Product {
@Column
private int id;
@Column;
private String productName;
@ManyToOne
private Order order;
//...getters setters
}

从设计的角度来看,我遇到了困境。我有以下方法,这些方法都是不正确的:

  1. 为客户定义一个 RestController 并提供所有 API 资源,如/customers、/customers/id/orders、/customers/id/orders/id/products 等。 有一个服务负责处理这些域。为每个域提供单独的 JPARepository。这里的"保持简单"是我为每个域都有单独的存储库,所以我只需要在相应的存储库类中提供查询方法,以便查找特定域的详细信息,即获取给定客户 ID 的订单。 但是,这让我认为杀死了使用 ORM 模型的目的,因为我正在通过他们的存储库类获取单个域。此选项将使所有 3 个存储库类都连接到服务类中,我认为这也不是一个好的设计。3 在这里看起来不错,但我的实际要求在 ORM 图中有 6 到 7 个域,因此这意味着在一个服务类中自动连接 6 个存储库。

  2. 一个 RestController 和一个 Service 类,如上述选项所示,但存储库类也是单一的。存储库仅为客户域创建。通过这种方式,我检索了带有其他 domaim 延迟加载的客户。这是为了满足"/客户"的 GET 请求。 为了满足"/customers/id/orders"的GET请求,我将再次使用客户存储库,检索给定ID的客户,然后返回订单列表。此外,对于"/customers/id/orders/id/products"的GET请求,我将需要在客户域中编写一个手动数据获取机制,以便它负责检索给定客户ID和orderID的产品列表。 这样,我使用了一个存储库,满足了使用ORM的目的,然后在客户域中添加了手动获取数据的方法。我看到的另一个缺点是,即使我有可用的 customerId 和 orderId,我也需要在客户域中获取完整的订单列表。我会根据 customerId 获取一个订单,并且 orderId 我为订单使用了单独的存储库。

  3. 两者都不正确,并且存在更好的方法。

我已经浏览了 Spring 文档的存储库和 ORM 的休眠文档。我浏览了多个教程,使用弹簧数据休息进行一对多映射,但我在不同的教程中发现了混合的方法。

这个问题对您来说看起来是重复的,因为我已经阅读了多篇关于 stackoverflow 的关于这个设计问题的帖子,但没有一个答案能给我解释我上面提到的权衡和选项。因此,我重新发布这个问题。

这是一种混合方法。 例如,在您的情况下,产品实体不需要与订单有@ManyToOne关系。想象一下,如果您的产品是 100 万个订单的一部分!您将查询产品以查找订单多少次?您将查询 findOrdersByProduct(Product( 而不是 findProductByOrder(Order(

  1. 想想你的用例。有时,如果您永远不会从关系所有者那里获取信息,那么进行一个方向映射是有意义的

  2. 考虑一下在查询实体时将提取的数据量(包括联接(。

  3. 例如,如果我正在获取一个组织,我是否需要获取其所有员工? 您的系统将进行折腾(延迟加载将节省您大部分时间,但如果您有 Angular,那么它将绑定并获取整个模型(。但是,与员工实体的组织建立多对一的关系确实是有意义的。

最新更新