【问题标题】:Parametric JpaRepository (or "subrepository")参数化 JpaRepository(或“子存储库”)
【发布时间】:2016-11-30 19:24:08
【问题描述】:

这是一个普遍的问题:我想以某种方式获取一个 JpaRepository 实例,它不会提供表中的所有数据,而是提供自定义过滤的数据集。换句话说,如果我能够以某种方式将自定义 AND 条件附加到特定 JpaRepository 的每个查询方法,则可以实现相同的效果。

让我们看一个例子,希望它有助于理解我的问题:

带有 Book 和 User 表的 Mind DB。每个 Book 实体都有一些属性,例如 title、description、pageCount、author 和 owner,即 @ManyToOne(一个 Owner 有很多 Books)。即 Book 表数据由所有者在逻辑上分成大组。在我的代码中,我使用findByName(String), findByAuthor(String) 之类的查询方法创建了接口BookRepository,但我想始终区分我目前正在服务的某个用户(所有者)返回的书籍。然后我需要将我的方法修改为findByNameAndOwner(String,User), findByAuthorAndOwner(String,User)等等。这很难看,感觉就像我缺少一些不错的 Spring Data 或 JPA 功能。

有没有办法拥有一些存储库工厂,例如:

User someOwner = ...;
BookRepository repo = BookByOwnerRepositoryFactory.getRepositoryFor(someOwner);

BookRepository 还是这样的:

interface BookRepository extends JpaRepository<Book,Long>
{
  List<Book> findByName(String name);
  List<Book> findByAuthor(String author);
  ...
}

使用:

List<Book> javaBooks = repo.findByName("Effective Java");

javaBooks 将仅包含someOwner 拥有的书籍,并且实际上是此类查询的结果:

select b from Book b where b.name='Effective Java' and b.owner_id=42

其中 42 是 someOwner.id。如您所见,最后一部分 and b.owner_id=42 应在内部附加到为 BookRepository 的查询方法生成的每个查询中。

【问题讨论】:

  • 我认为这种方法与 Spring Data JPA 的使用方式背道而驰。您向可能查看代码的人隐藏了一半的信息,这并不好。更重要的是,这意味着您每次调用服务时都会创建一个新实例,当您可以将它们保持为单例时会增加许多不必要的开销。

标签: java spring spring-data-jpa jpql


【解决方案1】:

您可以尝试使用 Querydsl 或 here 等规范

在存储库中,您将拥有作为参数具有条件的方法 findAll。

【讨论】:

    猜你喜欢
    • 2015-04-14
    • 1970-01-01
    • 2021-02-02
    • 2011-07-23
    • 2018-04-20
    • 1970-01-01
    • 2020-03-16
    • 1970-01-01
    • 2018-08-09
    相关资源
    最近更新 更多