查询方法中的Spring Data可选参数

时间:2022-09-11 16:31:35

I want to write some query methods in repository layer. This method must ignore null parameters. For example:

我想在存储库层中编写一些查询方法。此方法必须忽略null参数。例如:

List<Foo> findByBarAndGoo(Bar barParam, @optional Goo gooParam);

This method must be return Foo by this condition:

此方法必须通过以下条件返回Foo:

bar == barParam && goo == gooParam;

if gooParam not null. if gooParam was null then condition change to:

如果gooParam不为null。如果gooParam为null,则条件更改为:

bar == barParam;

Is there any solution? Can someone help me?

有什么解决方案吗?有人能帮我吗?

4 个解决方案

#1


1  

Too late to answer. Not sure about relationship between Bar and Goo. Check if Example can helps you.

回答太晚了。不确定Bar和Goo之间的关系。检查示例是否可以帮助您。

It worked for me. I have a similar situation, entity User have set of attributes and there is findAll method which search user based on attributes(which are optional).

它对我有用。我有类似的情况,实体用户有一组属性,并有findAll方法搜索用户基于属性(这是可选的)。

Example,

例,

  Class User{
    String firstName;
    String lastName;
    String id;
  }

  Class UserService{
     // All are optional
     List<User> findBy(String firstName, String lastName, String id){
        User u = new User();
        u.setFirstName(firstName);
        u.setLastName(lastName);
        u.setId(id);

        userRepository.findAll(Example.of(user));
        // userRepository is a JpaRepository class
     }
  }

#2


11  

I don't believe you'll be able to do that with the method name approach to query definition. From the documentation (reference):

我不相信你能用查询定义的方法名称方法做到这一点。从文档(参考):

Although getting a query derived from the method name is quite convenient, one might face the situation in which either the method name parser does not support the keyword one wants to use or the method name would get unnecessarily ugly. So you can either use JPA named queries through a naming convention (see Using JPA NamedQueries for more information) or rather annotate your query method with @Query

尽管获取从方法名称派生的查询非常方便,但是可能面临这样的情况:方法名称解析器不支持要使用的关键字,或者方法名称会变得不必要地丑陋。因此,您可以通过命名约定使用JPA命名查询(请参阅使用JPA NamedQueries获取更多信息)或者使用@Query注释查询方法

I think you have that situation here, so the answer below uses the @Query annotation approach, which is almost as convenient as the method name approach (reference).

我认为你有这种情况,所以下面的答案使用@Query注释方法,这几乎和方法名称方法(参考)一样方便。

    @Query("select foo from Foo foo where foo.bar = :bar and "
        + "(:goo is null or foo.goo = :goo)")
    public List<Foo> findByBarAndOptionalGoo(
        @Param("bar") Bar bar, 
        @Param("goo") Goo goo);

#3


1  

Complementing the answer of @chaserb, I personally would add the parameter as a Java8 Optional type to make it explicit in the signature of the method the semantics that is an optional filter.

作为@chaserb的答案的补充,我个人会将参数添加为Java8可选类型,以使其在方法的签名中显式显示作为可选过滤器的语义。

@Query("select foo from Foo foo where foo.bar = :bar and "
   + "(:goo is null or foo.goo = :goo)")
public List<Foo> findByBarAndOptionalGoo(
     @Param("bar") Bar bar, 
     @Param("goo") Optional<Goo> goo);

#4


-1  

You could code this yourself in just a few lines:

您可以自己编写代码,只需几行:

List<Foo> findByBarAndOptionalGoo(Bar bar, Goo goo) {
   return (goo == null) ? this.findByBar(bar) : this.findByBarAndGoo(bar, goo);
}

Otherwise, I don't know if Spring-Data supports this out of the box.

否则,我不知道Spring-Data是否支持开箱即用。

#1


1  

Too late to answer. Not sure about relationship between Bar and Goo. Check if Example can helps you.

回答太晚了。不确定Bar和Goo之间的关系。检查示例是否可以帮助您。

It worked for me. I have a similar situation, entity User have set of attributes and there is findAll method which search user based on attributes(which are optional).

它对我有用。我有类似的情况,实体用户有一组属性,并有findAll方法搜索用户基于属性(这是可选的)。

Example,

例,

  Class User{
    String firstName;
    String lastName;
    String id;
  }

  Class UserService{
     // All are optional
     List<User> findBy(String firstName, String lastName, String id){
        User u = new User();
        u.setFirstName(firstName);
        u.setLastName(lastName);
        u.setId(id);

        userRepository.findAll(Example.of(user));
        // userRepository is a JpaRepository class
     }
  }

#2


11  

I don't believe you'll be able to do that with the method name approach to query definition. From the documentation (reference):

我不相信你能用查询定义的方法名称方法做到这一点。从文档(参考):

Although getting a query derived from the method name is quite convenient, one might face the situation in which either the method name parser does not support the keyword one wants to use or the method name would get unnecessarily ugly. So you can either use JPA named queries through a naming convention (see Using JPA NamedQueries for more information) or rather annotate your query method with @Query

尽管获取从方法名称派生的查询非常方便,但是可能面临这样的情况:方法名称解析器不支持要使用的关键字,或者方法名称会变得不必要地丑陋。因此,您可以通过命名约定使用JPA命名查询(请参阅使用JPA NamedQueries获取更多信息)或者使用@Query注释查询方法

I think you have that situation here, so the answer below uses the @Query annotation approach, which is almost as convenient as the method name approach (reference).

我认为你有这种情况,所以下面的答案使用@Query注释方法,这几乎和方法名称方法(参考)一样方便。

    @Query("select foo from Foo foo where foo.bar = :bar and "
        + "(:goo is null or foo.goo = :goo)")
    public List<Foo> findByBarAndOptionalGoo(
        @Param("bar") Bar bar, 
        @Param("goo") Goo goo);

#3


1  

Complementing the answer of @chaserb, I personally would add the parameter as a Java8 Optional type to make it explicit in the signature of the method the semantics that is an optional filter.

作为@chaserb的答案的补充,我个人会将参数添加为Java8可选类型,以使其在方法的签名中显式显示作为可选过滤器的语义。

@Query("select foo from Foo foo where foo.bar = :bar and "
   + "(:goo is null or foo.goo = :goo)")
public List<Foo> findByBarAndOptionalGoo(
     @Param("bar") Bar bar, 
     @Param("goo") Optional<Goo> goo);

#4


-1  

You could code this yourself in just a few lines:

您可以自己编写代码,只需几行:

List<Foo> findByBarAndOptionalGoo(Bar bar, Goo goo) {
   return (goo == null) ? this.findByBar(bar) : this.findByBarAndGoo(bar, goo);
}

Otherwise, I don't know if Spring-Data supports this out of the box.

否则,我不知道Spring-Data是否支持开箱即用。