Spring数据JPA中findBy和findOneBy的区别

Posted

技术标签:

【中文标题】Spring数据JPA中findBy和findOneBy的区别【英文标题】:Difference between findBy and findOneBy in Spring data JPA 【发布时间】:2018-02-09 19:31:52 【问题描述】:

到目前为止,我所知道的是 FindBy 可以返回多个结果,而 FindOneBy 将返回单个结果或 null 当我们使用以下方式时。

List<Department> findByDepartmentName(String name);
Department findOneByDepartmentId(Long Id);

现在,我的问题是,我可以这样使用 findBy 吗?

Department  findByDepartmentId(Long Id);

如果是,

假设给定 ID 有多个记录。 findBydepartmentId 返回单条记录的依据是什么?

最后,什么时候或为什么不应该使用 findBy 代替 findOneBy?

【问题讨论】:

我也有同样的问题,你查清楚了吗? 【参考方案1】:

我可以这样使用findBy吗?部门findByDepartmentId(Long Id);

是的,从 Spring JPA 的角度来看,这种语法在技术上是正确的。尽管 Spring JPA 也可以通过查看返回类型的查询来推断您想要实现的目标。

基本上这些是返回类型的情况:

您的查询要返回单个值 - 您可以指定 basic typeEntity TOptional&lt;T&gt;CompletableFuture&lt;T&gt; 等。

您的查询要返回 T 的集合 - 您可以指定 List&lt;T&gt;Stream&lt;T&gt;Page&lt;T&gt;Slice&lt;T&gt; 等。

话虽如此,您的查询定义:

Department findByDepartmentId(Long Id);

表示您期望一个结果(因为您已将Entity T 指定为返回类型)。这将反映 Spring JPA 如何执行查询 - 它将在 javax.persistence.Query 接口上调用 getSingleResult(),如果多个对象满足条件,则会抛出 exception

findBydepartmentId 返回单条记录的依据是什么?

基于该Id的对象只有一个,否则会抛出异常。

何时或为什么不应该使用findBy 代替findOneBy

这两个有不同的含义,不能互换。

findOneBy 总是导致getSingleResult() 被调用。

findBy 具有不同的行为,具体取决于返回类型 - 根据上面给出的定义。

【讨论】:

【参考方案2】:

findOneByXX 将确保只有一个值或没有值,如果有 2 个值将引发异常。

但是findByXX 不会检查唯一性。

【讨论】:

Optional findBy 至少在使用自定义 @Query 时返回 IncorrectResultSizeDataAccessException findByXX 可能会抛出此异常,具体取决于声明的结果类型。实体 T 或 Optional 仍将导致调用 getSingleResult() 如果超过 1 条记录符合条件,则会抛出 IncorrectResultSizeDataAccessException。【参考方案3】:

我已经做了一些测试,Spring Data 忽略了方法(finddelete、...)和 By 之间的所有字符。

在https://github.com/spring-projects/spring-data-commons/blob/14d5747f68737bb44441dc511cf16393d9d85dc8/src/main/java/org/springframework/data/repository/query/parser/PartTree.java#L65 中是\pLu.*? 部分。

Spring Data 仅使用返回类型来决定如何处理响应。

因此,即使语义上不正确,也可以定义以下这些方法。

Department findAllByDepartmentId(Long Id);
List<Department> findOneByDepartmentName(String name);

【讨论】:

以上是关于Spring数据JPA中findBy和findOneBy的区别的主要内容,如果未能解决你的问题,请参考以下文章

请教关于Spring Data JPA动态查询参数的问题

srping jpa 怎么用save

spring data jpa getOne抛出LazyInitializationException而findBy没有

spring data jpa getOne 抛出 LazyInitializationException 和 findBy 不

Spring Data JPA findBy一个集合[重复]

Spring Data JPA 之间 findBy / findAllBy 的区别