【发布时间】: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