【问题标题】:How to write query in Spring Data JPA with multiple nullable parameters?如何在 Spring Data JPA 中编写具有多个可为空参数的查询?
【发布时间】:2019-06-21 20:11:15
【问题描述】:

我有一个这样的实体类:

class EntityClass {
    UUID id;
    String param1, param2, param3;
    //Getters and Setters
}

我的服务类将有一些这样的方法来利用所有这样的列,并且我希望能够使用相同的存储库方法处理所有请求,而不是为每种组合的情况编写多个存储库方法参数为空。

class ServiceClass {
    List<EntityClass> getAllBy(List<String> param1, List<String> param2, String param3) {
        return repositoryInterface.customFindAll(param1, param2, param3);
    }
}

现在我的存储库类应该有这个方法。但我希望能够处理 {param1, param2, param3} 的任何组合可以为 null 的情况,例如 {param1 = null 或 empty, param2 != null, param3 != null} 或 {param1 = null or empty , param2 = null 或空, param3 != null} 等

存储库方法customFindAll 基本上应该能够搜索实体表以检查param1 列值是否在发送的任何值列表中等。如果不是null

那么我应该如何处理 Spring JPA 中的原生查询来做这样的事情,而不是为不同的组合创建不同的方法呢?

interface RepositoryInterface extends JpaRepository<EntityClass, UUID> {
    @Query(value = "FILL THE QUERY", nativeQuery = true)
    List<EntityClass> customFindAll(@Param("param1") List<String> param1, @Param("param2") List<String> param2, @Param("param3") String param3)
}

【问题讨论】:

  • 如果它们为空,为什么需要执行此方法?即使在数据库中也没有什么可与null
  • @Deadpool 是的,这就是我想要做的 - 如果我的服务方法接收到值列表,然后在 :param1 中搜索类似 param1,但如果它接收到 param1 的空值,请不要搜索它。
  • 你为什么不在服务类中检查它们?
  • @Deadpool 在检查服务类并基于该调用适当的存储库方法?如果是这样,那么我将不得不创建许多存储库方法 - 每个组合一个,对吗?
  • 当所有内容都不为空时调用该方法,如果某些内容为空或为空不要调用,我相信如果它们中的任何一个为空或为空也没用

标签: java sql spring spring-boot spring-data-jpa


【解决方案1】:

解决这个问题的一般方法是使用这样的 where 子句:

WHERE (:param1 IS NULL OR param1 IN :param1) ...

但我认为您不能对列表值绑定参数进行is null 检查。 但是你可以use SpEL expressions for this

这应该可以解决问题:

SELECT id, param1, param2, param3
FROM EntityClass
WHERE (:#{#param1 == null ? 0 : 1} = 0 OR param1 IN :param1) 
AND   (:#{#param2 == null ? 0 : 1} = 0 OR param2 IN :param2) 
AND   (:#{#param3 == null ? 0 : 1} = 0 OR param3 IN :param3) 

评论可能是正确的:IN 在空参数或null 参数上可能不会被解析为合法的 SQL 语句。 在这种情况下,您可以使用更多的 SpEL 力量(如上重复 3 次):

( param1 IN :#{(#param1 == null || #param1.isEmpty()) ? java.util.Collections.singletonList(#param1) : #param1})

当然,这一切都变得相当丑陋,所以你可能会更好creating your query dynamically using Specifications

【讨论】:

  • 但是如果 :param1 为 NULL 或空列表,它不会尝试检查 NULL 或 () 会引发错误吗?
猜你喜欢
  • 2020-06-09
  • 1970-01-01
  • 2018-08-16
  • 1970-01-01
  • 2022-01-12
  • 1970-01-01
  • 2014-09-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多