在Spring Data JPA的“入门”示例中,我们创建了一个扩展CrudRepository的接口。但是,它只处理一个实体:
import org.springframework.data.repository.CrudRepository;
interface MyEntityRepository extends CrudRepository<MyEntity, Long> {
// methods...
}
在真实的应用程序中,有许多实体(表),我们需要对它们执行CRUD操作。将Spring Data JPA存储库与多个(相关或不相关)实体一起使用的正确方式是什么?
我是否必须为每个实体创建接口并逐个自动连接它们(这听起来非常疯狂)?
发布于 2015-09-11 20:43:29
Spring Data使用领域驱动设计中定义的存储库概念。存储库基本上表示聚合根的集合,而聚合根又是您将访问的一些实体,并对其他实体实施业务约束。例如,如果你有一个由LineItem
组成的Order
,Order
将是聚合根,因为它控制着LineItem
的生命周期等等。因此,你应该为Order
定义一个存储库,而不是为LineItem
定义一个存储库。因此,到目前为止,你并不是为所有实体创建存储库。它基本上是域建模中决定哪些实体成为聚合根的重要部分。
另一个方面是,存储库通常由持久性机制支持,您不希望将业务逻辑直接编码到持久性API以保持其可测试性,而不必处理持久性API。这意味着,存储库将包含查询方法,这些方法基本上表示集合中所有聚合根的子集,并由特定于存储的查询实现支持。这只能通过聚合根的方式来实现。
第三也是最后一个方面是,存储库可以帮助你更容易地限制对持久化操作的访问,因为你可以使用包范围来强制客户端甚至使用专用服务,并且基本上隐藏特定包中特定域对象的所有持久化操作。使用像EntityManager
这样的通用持久性API,您将失去对谁从系统中的任何点实际读取内容的控制,因为它可以在持久性上下文中持久化每个类型。
总而言之:存储库表示聚合的集合,并允许访问该集合的专用子集。Spring Data使得创建它们尽可能简单,而替代方案在架构上不那么可取(参见上面的推理)或更麻烦(如果它们必须手动实现)。您为哪些实体创建存储库取决于您对域进行建模的方式,其中哪些实体是聚合根。
发布于 2015-09-08 18:49:08
你是对的。对于您希望使用Spring数据的每个实体,您需要创建一个接口来扩展其中一个存储库接口,然后将该接口自动绑定到您的类中。对于要执行crud/query操作的每个实体,您只需要其中一个。如果包含在通过级联关系创建/管理的另一个实体中的实体,则不需要显式地为该实体创建存储库。
就您的观点而言,必须为每个实体创建一个接口并对其进行自动绑定似乎有点繁琐,但这就是Spring Data的设计方式,也是它能够自动为您生成数据访问代码的原因。如果你想写你自己的数据层,你显然不需要这么做。
https://stackoverflow.com/questions/32464680
复制