【问题标题】:Implement JpaRepository interface with custom method使用自定义方法实现 JpaRepository 接口
【发布时间】:2020-05-02 23:07:39
【问题描述】:
我是 Spring Boot 新手,所以我有几个基本问题。
当我们定义一个扩展 JpaRepository
的
Repository 接口
@Repository
public interface UserInfoRepository extends JpaRepository<UserInfo, Long> {
Optional<UserInfo> findByEmail(String email);
List<UserInfo> findAllByEmail(String email);
}
这些方法可以从Service类中调用(我们可能甚至不需要提及这两个方法)。到目前为止,一切都很好。
问题:
方法findByEmail是如何定义的?它在幕后是怎么称呼的?
如果我们想用原生 SQL 添加自定义方法 findUserAction 怎么办?在这种情况下,我们需要在interface UserInfoRepository 中声明它并在UserInfoRepositoryImpl 类中定义它。那样的话,我们是不是也需要定义其他已有的方法了?
任何帮助将不胜感激。提前致谢! :)
【问题讨论】:
标签:
java
spring-boot
spring-data-jpa
spring-data
【解决方案1】:
Spring Data 允许您定义查询方法的方式有多种。
按您必须完成的工作量(以及您获得的灵活性)排序:
预定义的方法。根据您选择作为存储库基础的接口,您可以免费获得一堆方法:那些在接口中声明的方法。您可以选择 CrudRepository、PagingAndSortingRepository、JpaRepository、QueryByExampleExecutor 和 JpaSpecificationExecutor。这些接口的方法在属于 Spring Data 的类中实现。例如SimpleJpaRepository。
查询派生。在这里,您可以只声明一个具有特定命名方案的方法。 Spring Data 将解析方法名称并从中构造一个查询,绑定您的参数并执行它。查询是使用 Jpa Criteria API 创建的。
查询注释/命名查询。您可以自己提供查询,方法是添加 @Query 注释或在实体上声明命名查询或将其放入属性文件中。 Spring Data 会找到它并执行它。它还将添加漂亮的东西以添加分页,如果您选择使用这些参数,它将通过 SpEL 处理您的参数。
最后,您可以提供自己的实现,您可以在其中执行 Java 允许您执行的操作:使用 EntityManager 或 JdbcTemplate 查询数据库,根本不访问数据库,而是执行完全不同的操作.
总的来说,整个过程是这样的:如果要注入存储库,Spring Data 会创建一个代理来实现存储库中声明的所有方法。在该代理中,Spring Data 将分析方法调用,确定上述哪种情况适用并执行它。实际上,决定使用什么过程是在启动时完成的,但这对于理解它并不重要。
实现方法的所有这些策略都是相互独立的,因此您可以为存储库中的每个方法使用不同的策略。