如何在Spring Data JPA中使用多个可为空的参数编写查询?

时间:2019-01-28 18:56:20

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

我有一个这样的Entity类:

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

我的Service类将具有类似这样的方法以利用所有此类列,并且我希望能够使用相同的存储库方法处理所有请求,而不是针对每种情况(组合使用)编写多个存储库方法的参数为空。

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或为空,param2!= null,param3!= null}或{param1 = null或为空,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)
}

1 个答案:

答案 0 :(得分:0)

通常的方法是使用类似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的{​​{1}}可能只是不解析为合法的SQL语句。 在这种情况下,您可以使用更大的SpEL力(如上所述重复三遍):

null

当然,所有这些都变得很丑陋,所以您最好使用creating your query dynamically using Specifications