搜索带有查询的sl和spring数据的A或B的位置

时间:2019-02-26 07:58:52

标签: spring-data-rest querydsl

http://localhost:8080/users?firstName=a&lastName=b --->其中firstName = a和lastName = b 如何使其成为--->其中firstName = a或lastName = b

但是当我设置QuerydslBinderCustomizer自定义

@Override
default public void customize(QuerydslBindings bindings, QUser user) {
    bindings.bind(String.class).all((StringPath path, Collection<? extends String> values) -> {
        BooleanBuilder predicate = new BooleanBuilder();
        values.forEach( value -> predicate.or(path.containsIgnoreCase(value) );
    });

}

http://localhost:8080/users?firstName=a&firstName=b&lastName=b --->其中(firstName = a或firstName = b)和lastName = b

AND的参数似乎不同。与我设置的参数相同(predicate.or / predicate.and)

如何像这样用AND使其成为不同的参数---> where firstName = a或firstName = b或lastName = b? 谢谢。

1 个答案:

答案 0 :(得分:0)

您当前的请求参数分组为List firstName和String lastName。我看到您想保留不带绑定的请求参数,但是在这种情况下,这会使您的工作更加轻松。

我的建议是创建一个带有请求参数的新类:

public class UserRequest {
    private String lastName;
    private List<String> firstName;
    // getters and setters
}

对于QueryDSL,您可以创建一个构建器对象:

 public class UserPredicateBuilder{

     private List<BooleanExpression> expressions = new ArrayList<>();

     public UserPredicateBuilder withFirstName(List<String> firstNameList){
          QUser user = QUser.user;
          expressions.add(user.firstName.in(firstNameList));
          return this;
     }
     //.. same for other fields

     public BooleanExpression build(){
        if(expressions.isEmpty()){
           return Expressions.asBoolean(true).isTrue();
        }
        BooleanExpression result = expressions.get(0);
        for (int i = 1; i < expressions.size(); i++) {
           result = result.and(expressions.get(i));
        }
        return result;
     }
 }

然后您可以将构建器用作:

 public List<User> getUsers(UserRequest userRequest){
       BooleanExpression expression = new UserPredicateBuilder()
                                      .withFirstName(userRequest.getFirstName())
                                    // other fields
                                      .build();
       return userRepository.findAll(expression).getContent();
 }

这是推荐的解决方案。 如果您确实想保留当前参数而没有绑定(它们仍然需要某种验证,否则它可能会在查询dsl绑定中引发Exception) 您可以按路径将它们分组:

Map<StringPath,List<String>> values //示例firstName => a,b

,然后根据地图创建布尔表达式:

   //initial value
  BooleanExpression result = Expressions.asBoolean(true).isTrue();
  for (Map.Entry entry: values.entrySet()) {
       result = result.and(entry.getKey().in(entry.getValues());
  }
  return userRepository.findAll(result);