Spring Data - 如果参数为空值,则忽略该参数

Pan*_*nos 25 spring spring-data spring-boot

我想要一个带有两个参数的spring数据存储库接口.有没有办法让它有以下行为?

MyObject findByParameterOneAndParameterTwo( String parameterOne, String parameterTwo);
Run Code Online (Sandbox Code Playgroud)

如果两个参数都有一个值,我希望它能正常运行并为两个值执行"AND".

例如,如果第二个参数为null,则它仅搜索ParameterOne

有什么建议?

Kad*_*rat 25

我不确定存储库方法命名是否可行,但你可以使用@Querylike

(:parameterOne is null or parameter1 = :parameterOne) and (:parameterTwo is null or parameter2 = :parameterTwo)
Run Code Online (Sandbox Code Playgroud)

  • 它仅适用于字符串值。它不适用于任何其他类型。此外,它不适用于 IN 子句,因为 null 或空检查不适用于列表。 (2认同)

Abd*_*han 10

目前这是不可能的Spring-data-jpa.

有一JIRA 关于这个目前仍在调查Spring团队.

在此输入图像描述

但是,如果您需要解决方法,可以签出一个简单的条件查询示例.


Tsv*_*kov 7

这是这样做的方法:

@Query("SELECT c FROM Customer c WHERE (:name is null or c.name = :name) and (:email is null"
      + " or c.email = :email)")
    List<Customer> findCustomerByNameAndEmail(@Param("name") String name, @Param("email") String email);
Run Code Online (Sandbox Code Playgroud)


Dov*_*vmo 5

这里缺少的一种解决方案是Spring Data JPA的Query by Example功能,并利用ExampleMatcher#ignoreNullValues正是为解决此问题而构建的。自定义查询和查询构建器都没有必要。

此Spring数据查询:

ExampleMatcher matcher = ExampleMatcher.matching().withIgnoreNullValues();
Example<MyObject> exampleQuery = Example.of(new MyObject("foo", null), matcher);
List<MyObject> results = repository.findAll(exampleQuery);
Run Code Online (Sandbox Code Playgroud)

产生如下查询:

select * 
from myObject 
where parameter1 = "foo"
Run Code Online (Sandbox Code Playgroud)

而以下:

ExampleMatcher matcher = ExampleMatcher.matching().withIgnoreNullValues();
Example<MyObject> exampleQuery = Example.of(new MyObject("foo", "bar"), matcher);
List<MyObject> results = repository.findAll(exampleQuery);
Run Code Online (Sandbox Code Playgroud)

产量:

select * 
from myObject 
where parameter1 = "foo"
and parameter2 = "bar"
Run Code Online (Sandbox Code Playgroud)

很酷!

注意:您必须对Repository界面做的一件事就是添加QueryByExample界面。您可以通过QueryByExample直接扩展接口或通过以下方式隐式地实现此目的JpaRepository

public interface MyObjectRepository extends JpaRepository<MyObject, Long> {}
Run Code Online (Sandbox Code Playgroud)

  • 真棒:正是我正在寻找的。如果有人正在扩展 JPARepository,那么您不需要扩展 QueryByExample 接口,因为 JPA 存储库已经扩展了它。 (2认同)
  • @Wiqi 上面的建议不查询由 `#withIgnoreNullValues` 指定的 `null` 值。可以使用`withIncludeNullValues` 和/或`NullHandler` 来修改并更好地控制该行为。 (2认同)

小智 5

试试这个Kolobok

@FindWithOptionalParams
Iterable<MyObject> findByParameterOneAndParameterTwo( String parameterOne, String parameterTwo);
Run Code Online (Sandbox Code Playgroud)