我需要哪些实体来创建Spring Data存储库?

Yas*_*muş 4 spring jpa spring-data spring-data-jpa

在Spring Data JPA的"入门"示例中,我们创建了一个扩展CrudRepository的接口.但是它只处理一个实体:

import org.springframework.data.repository.CrudRepository;

interface MyEntityRepository extends CrudRepository<MyEntity, Long> {
  // methods...
}
Run Code Online (Sandbox Code Playgroud)

在实际应用程序中,有许多实体(表),我们需要为它们执行CRUD操作.使用具有多个(相关或不相关)实体的Spring Data JPA存储库的正确方法是什么?

我是否必须为每个实体创建接口并逐个自动装配它们(这听起来非常疯狂)?

Oli*_*ohm 12

Spring Data使用域驱动设计中定义的存储库概念.存储库基本上代表聚合根的集合,而聚合根又是您的一些实体,您将访问这些实体并对其他实体施加业务约束.例如,如果你有一个s Order组成LineItem,那么Order'd'就是聚合根,因为它控制着LineItems 的生命周期等等.因此,你要为它定义一个存储库,Order而不是为它定义存储库LineItem.所以到目前为止,并不是你创建存储库的所有实体.在您的域建模中,它基本上是决定哪些实体成为聚合根的重要部分.

另一个方面是存储库通常由持久性机制支持,并且您不希望将业务逻辑直接编码到持久性API,以保持其可测试性,而无需处理持久性API.这意味着,存储库将包含查询方法,这些查询方法基本上表示集合中所有聚合根的子集,并由特定于商店的查询实现支持.这只能通过聚合根方式实现.

第三个也是最后一个方面是存储库可以帮助您更轻松地限制对持久性操作的访问,因为您可以使用例如包范围来强制客户端甚至使用专用服务,并基本上隐藏某个包中某个域对象的所有持久性操作.使用通用持久性API,EntityManager您无法控制实际从系统中的任何位置读取内容的人,因为它可以在持久性上下文中保留每种类型.

总结一下:存储库代表聚合的集合,并允许访问该集合的专用子集.Spring Data使这些替代方案尽可能简单,因为替代方案在架构上不太理想(参见上面的推理)或更麻烦(如果必须手动实现).您创建存储库的实体取决于您对域的建模方式,其中哪些是聚合根.


Chr*_*son 4

你是对的。对于要使用 Spring Data 的每个实体,您需要创建一个扩展存储库接口之一的接口,然后将该接口自动装配到您的类中。对于要对其执行增删改查/查询操作的每个实体,您只需要其中之一。如果一个实体包含在通过级联关系创建/管理的另一个实体中,则无需为该实体显式创建存储库。

就您的观点而言,必须创建一个接口并为每个实体自动装配它似乎有点冗长,但这就是 Spring Data 的设计方式,并且使它能够自动为您生成数据访问代码。如果您想编写自己的数据层,显然您不必这样做。