Spring数据JPA和可以为null的参数

Seb*_* S. 28 java parameters null spring-data-jpa

我的理解是,使用Spring数据JPA我不能有一个查询方法来获取列等于给定的非null方法参数的所有行,并且当method参数为null时,使用相同的方法获取此列为NULL的所有行.

那是对的吗?

所以我必须在我的JAVA代码中区分它,我必须使用一个单独的查询方法显式询问空值,如下例所示?

// Query methods
List<Something> findByParameter(Parameter parameter);
List<Something> findByParameterIsNull();

...

List<Something> result = new ArrayList<>();

if (parameter == null)
  result = findByParameterIsNull();
else
  result = findByParameter(parameter);
Run Code Online (Sandbox Code Playgroud)

这很糟糕,如果我有4个参数可以为null并且必须编码16种不同的查询方法.

Lau*_*t B 18

你是对的.

已经发出请求以支持更好地处理空参数. https://jira.spring.io/browse/DATAJPA-121

在您的情况下,我建议您编写存储库实现并使用自定义CriteriaQuery来处理您的案例.

您还可以使用带有is null语法的@Query注释:

@Query("[...] where :parameter is null"
public List<Something> getSomethingWithNullParameter();
Run Code Online (Sandbox Code Playgroud)

编辑

从Spring数据jpa 2.0开始,spring现在支持@Nullable注释.这有助于处理传递的null参数.

文档:

@Nullable - 用于参数或返回值,可以为null.

  • Nullable如何帮助解决这个问题?如果我们将参数注释为@Nullable,我认为Spring Data不会将查询转换为"is null". (4认同)
  • 我已经扩展了答案:当使用Spring数据JPA` @ Query`注释时,您必须使用两个单独的查询方法.一个用于处理空值,另一个用于非空值.但是当使用由Spring数据解析器解析的查询方法(没有`@ Query`注释)时,可以使用一个方法处理null或非null值! (2认同)
  • @Query`:parameter为null`不起作用。它会失败并带有异常,但是即使不会,SQL也会将null视为未知。因此,未知与未知并不相等。在SQL中,基本上'null'与'null'不相等。 (2认同)

mvm*_*vmn 12

似乎Query by Example可能就是您所需要的.

Query by Example是Spring Data中的一个新功能(自版本Hopper出版,2016年4月),它允许用这样的代码创建简单的动态查询

Person person = new Person();                          
person.setFirstname("Dave");                           

ExampleMatcher matcher = ExampleMatcher.matching()     
  .withIncludeNullValues();                        

Example<Person> example = Example.of(person, matcher);

personRepository.count(example);
personRepository.findOne(example);
personRepository.findAll(example);
Run Code Online (Sandbox Code Playgroud)

方法count/findOne/findAll称取的一个实例org.springframework.data.domain.Example作为参数(和它们中的一些也采取分拣/分页参数)从正在到来org.springframework.data.repository.query.QueryByExampleExecutor<T>接口,其通过扩展org.springframework.data.jpa.repository.JpaRepository<T, ID extends Serializable>接口.

简而言之,所有JpaRepository实例现在都有这些方法.


GMs*_*soF 5

从2018年6月开始的今天,通过查看https://jira.spring.io/browse/DATAJPA-121is null如果您的参数为空,查询将自动形成。

我在我的项目中做到了,这是真的:

compile group: 'org.springframework.data', name: 'spring-data-jpa', version: '2.0.7.RELEASE'
Run Code Online (Sandbox Code Playgroud)

-

public interface AccountDao extends CrudRepository<T, ID> {

    //this can accept null and it will become isNull
    public List<MyAccount> findByEmail(String email);

}
Run Code Online (Sandbox Code Playgroud)

如果参数为null:

select
        myaccount0_.id as id1_0_,
        myaccount0_.email as email2_0_,
        myaccount0_.password as password3_0_,
        myaccount0_.user_id as user_id4_0_ 
    from
        my_account myaccount0_ 
    where
        myaccount0_.email is null
Run Code Online (Sandbox Code Playgroud)

如果参数不为null:

select
        myaccount0_.id as id1_0_,
        myaccount0_.email as email2_0_,
        myaccount0_.password as password3_0_,
        myaccount0_.user_id as user_id4_0_ 
    from
        my_account myaccount0_ 
    where
        myaccount0_.email=?
11:02:41.623 [qtp1507181879-72] TRACE o.h.type.descriptor.sql.BasicBinder - binding parameter [1] as [VARCHAR] - [testing@hotmail.com] 
Run Code Online (Sandbox Code Playgroud)

然后是一个有趣的问题,一些开发人员希望更好地控制它是否忽略查询中的参数(如果该参数为null,这仍在https://jira.spring.io/browse/DATAJPA-209中进行调查)。


fvu*_*vic 5

我发现了一些东西...如果您将参数放在这样的jpa方法中

@Param("value") String value,
Run Code Online (Sandbox Code Playgroud)

那么它可以为null,在查询中您将具有以下条件:

(table.value = :value OR :value IS NULL)
Run Code Online (Sandbox Code Playgroud)

如果该值为null,它将自动返回true;如果不为null,则它将在表中搜索该值。

  • 让我感动的一件事是,如果我这样做了,它就不起作用了 (:value IS NULL OR table.value = :value) 它告诉我我需要强制转换 :value 但按照你写的顺序进行操作。 (3认同)
  • 如果值是集合,则 :vales is null 将不起作用。 (2认同)
  • 它只会跳过传递空值的选择查询字段。可能会导致额外的结果集。 (2认同)