您是否应该在 JPA 中的每个表都有一个存储库?

2022-01-18 00:00:00 java jpa spring-data spring-data-jpa

您是否应该在 JPA 中为每个表创建一个存储库?如果不是,如何解析存储库数据库中的泛型?

Are you supposed to have one repository per table in JPA? If not, how do you resolve the generics in the repository database?

例如,下面是一个 StoreRepository.它处理 Store 对象上的 CRUD 操作.如果我希望存储库也保存 StoreEvent 对象,我将如何更改下面的接口以容纳这两个对象?

For example, below is a StoreRepository. It handles CRUD operations on the Store object. If I wanted the repository to save a StoreEvent object as well, how would I go about changing the interface below to accommodate both objects?

@Repository
public interface StoreRepository extends JpaRepository<Store, String> {
    public Store findByGuid(String guid);
}

推荐答案

作为存储库是一个源自 Domain 的概念驱动设计,考虑数据库表是错误的方法.根据定义,您可以从存储库访问聚合根.实际上,存储库正在模拟这些的集合.

As repository is a concept derived from Domain Driven Design, thinking about database tables is the wrong approach. By definition you access aggregate roots from a repository. Effectively a repository is simulating a collection of these.

现在什么形成聚合根?可能更有趣:什么不是?当然,这高度依赖于您的域,但让我在这里举个例子.包含 LineItemsOrder 通常被建模为聚合根.这是由于 Order 的组合性质造成的.如果没有周围的 Order,则 LineItem 将不存在.

Now what forms an aggregate root? Probably even more interesting: what does not? That's, of course, highly dependent on your domain, but let me give you an example here. An Order containing LineItems usually is modeled as an aggregate root. This is due to the composition nature of the Order. A LineItem would not exist without a surrounding Order.

通常持久性访问机制应该遵循领域原则.因此,您可以将 OrderLineItem 建模为 @Entity 类,但只创建一个 OrderRepository,因为它们形成聚合根,有效控制对象图中的一致性规则.

Usually the persistence access mechanisms should follow the domain principles. Thus, you'd model both Order and LineItem as @Entity classes but only create an OrderRepository, as they form the aggregate root and effectively control the consistency rules within the object graph.

我们还强烈建议不要使用商店特定的存储库基础接口,因为它们 - 顾名思义 - 公开商店细节(例如 flush()) 发送给他们不应该知道的客户,如果可能的话.在我的回答此处中了解更多信息.

We also strongly recommend not to use the store specific repository base interfaces as they - as the name suggests - expose store specifics (e.g. flush()) to the clients of which they shouldn't be aware, if possible. Read more on that in my answer here.

相关文章