Java Spring数据Rest:使用逻辑OR链接的查询参数

Java Spring数据Rest:使用逻辑OR链接的查询参数,java,spring,spring-data-rest,querydsl,Java,Spring,Spring Data Rest,Querydsl,我有一个由以下存储库公开的实体: public interface InsertRepository extends PagingAndSortingRepository<InsertEntity, Long>, QueryDslPredicateExecutor<InsertEntity>, QueryDslBinderCustomizer<QInsertEntity> { @Override default void customize(Q

我有一个由以下存储库公开的实体:

public interface InsertRepository extends PagingAndSortingRepository<InsertEntity, Long>, QueryDslPredicateExecutor<InsertEntity>, QueryDslBinderCustomizer<QInsertEntity> {
    @Override
    default void customize(QuerydslBindings bindings, QInsertEntity insert) {
        bindings.bind(String.class).all(StringPath path, Collection<? extends String> values) -> {
            BooleanBuilder predicate = new BooleanBuilder();
            values.forEach(value -> predicate.or(path.containsIgnoreCase(value)));

            return predicate;
        });
    }
}
public interface InsertRepository扩展了分页和排序存储库、querydsl谓词执行器、querydsl bindercustomizer{
@凌驾
默认void自定义(QuerydslBindings绑定,Qinsertity插入){

bindings.bind(String.class).all(StringPath路径,集合)您可以使用命名参数,例如
示例53.使用命名参数

public interface UserRepository扩展了JpaRepository{
@查询(“从用户u中选择u,其中u.firstname=:firstname或u.lastname=:lastname”)
用户findByLastnameOrFirstname(@Param(“lastname”)字符串lastname,
@Param(“firstname”)字符串firstname);
}

您可以使用命名参数,如
示例53.使用命名参数

public interface UserRepository扩展了JpaRepository{
@查询(“从用户u中选择u,其中u.firstname=:firstname或u.lastname=:lastname”)
用户findByLastnameOrFirstname(@Param(“lastname”)字符串lastname,
@Param(“firstname”)字符串firstname);
}

由@kafkas提供的答案一点也不准确。它有很多问题:

  • 注释
    @Query
    已过时-Spring会自动为您执行此操作,您只需正确键入方法的名称
  • 注释
    @Param
    已过时-Spring自动按给定顺序获取参数,并与方法名称中的参数匹配
  • 返回单用户实体,但仍使用
    findBy
    而不是
    findOne
    ——如果找到多条记录,则会导致错误
  • 最后一个但并非最不重要的方法将不会使用
    LIKE
    比较,而是使用equals。如果您希望启动SQL查询,如:
    …WHERE firstname LIKE“%name%”,则应使用
    findbyxxcontaining
  • 使用Spring,如果不需要,我建议不要使用JpaRepository。最简单的实现是
    crudepository
    ,它涵盖了大多数用例
  • 总之,您的方法应该简化,如下所示:

    public interface UserRepository扩展了crudepository{
    用户findOneByLastnameContainingOrFirstnameContaining(字符串lastname,字符串firstname);
    }

    这将导致查询:


    从用户u中选择*,其中u.lastname(如“%lastname”)或u.firstname(如“%firstname%”;

    由@kafkas提供的答案一点也不准确。它有很多问题:

  • 注释
    @Query
    已过时-Spring会自动为您执行此操作,您只需正确键入方法的名称
  • 注释
    @Param
    已过时-Spring自动按给定顺序获取参数,并与方法名称中的参数匹配
  • 返回单用户实体,但仍使用
    findBy
    而不是
    findOne
    ——如果找到多条记录,则会导致错误
  • 最后一个但并非最不重要的方法将不会使用
    LIKE
    比较,而是使用equals。如果您希望启动SQL查询,如:
    …WHERE firstname LIKE“%name%”,则应使用
    findbyxxcontaining
  • 使用Spring,如果不需要,我建议不要使用JpaRepository。最简单的实现是
    crudepository
    ,它涵盖了大多数用例
  • 总之,您的方法应该简化,如下所示:

    public interface UserRepository扩展了crudepository{
    用户findOneByLastnameContainingOrFirstnameContaining(字符串lastname,字符串firstname);
    }

    这将导致查询:


    SELECT*FROM User u,其中u.lastname(如“%lastname”)或u.firstname(如“%firstname%”;”

    这将要求我创建一个新的控制器方法,该方法反过来调用该方法。我正试图通过正常的REST接口公开该行为,因此我不需要为查询调用特定的方法。框架将自动为您生成一个
    /search/findbylastname或firstname
    端点。这有一些严重的问题…请查看我的答案以了解详细信息。这将需要我创建一个新的控制器方法,该方法反过来将调用该方法。我正试图通过正常的REST接口公开该行为,因此我不需要调用特定的me查询方法。框架将自动为您生成一个
    /search/findbylastname或firstname
    端点。这有一些严重问题…请查看我的答案以了解详细信息。TypeBinder$all()允许您自定义按路径或按类指定的多值绑定。但即使您“按类”自定义绑定,也可以,查询参数不全局处理。对于instance@MarcTarin好的,如果我理解正确,我无法使用
    自定义
    方法完成我所需要的,对吗?例如
    ?description=searchText&description=searchInt
    将为您提供
    其中类似“%searchText%”的描述或类似“%searchI”的描述nt%'
    customerName
    的出现被作为一个单独的子句处理,所有子句都与and连接。因此,据我所知,您无法使用
    customize
    方法完成所需的任务。好的,非常感谢您-我想我将使用自定义查询。TypeBinder$all()允许您自定义按路径或按类指定的多值绑定。但即使在“按类”自定义绑定时,查询参数不全局处理。对于instance@MarcTarin好的,如果我理解正确,我无法使用
    自定义
    方法完成我需要的,对吗?例如
    ?description=searchText&description=searchInt
    public interface UserRepository extends JpaRepository<User, Long> {
       @Query("select u from User u where u.firstname = :firstname or u.lastname = :lastname")
       User findByLastnameOrFirstname(@Param("lastname") String lastname,
                                   @Param("firstname") String firstname);
    }