将QueryDSL链接到restful get的简单方法

时间:2017-04-19 04:15:27

标签: java querydsl

我想做一个简单的条件JPA查询,以从 bankAccountNumber branchCode 获取BankTransactions列表。

我的案例是

  1. 获取(“12345678”,“123”)获取银行帐户 12345678 和分支 123 的所有交易

  2. 获取(null,“123”)获取所有银行帐户和分支机构的所有交易 123

  3. get(null,null)获取所有交易

  4. 我已经编写了这段代码,但由于BooleanExpression没有初始值,所以看起来真的很臭。

    我认为我误解了API。我该如何清理它?

    (我误解了API吗?)

    public Page<BankTransactions> get(
      @RequestParam(required = false) String bankAccountNumber,
      @RequestParam(required = false) String branchCode,
      Pageable pageable) {
    
      QBankTransactions q = QBankTransactions.bankTransactions;
      BooleanExpression expression = null;
    
      if (bankAccountNumber != null) {
        if (expression == null) {
          expression = q.bankAccountNumber.eq(bankAccountNumber);;
        } else {
          expression.and(q.bankAccountNumber.eq(bankAccountNumber));
        }
      }
      if (branchCode != null) {
        if (expression == null) {
          expression = q.branchCode.eq(branchCode);
        } else {
          expression.and(q.branchCode.eq(branchCode));
        }
      }
      if (expression != null) {
        Page<BankTransactions> response = repository.findAll(expression, pageable);
        return response;
      } else {
        Page<BankTransactions> response = repository.findAll(pageable);
        return response;
      }
    }
    

3 个答案:

答案 0 :(得分:1)

简单地将谓词传递给method参数。 More info

public Page<BankTransactions> get(
  @QuerydslPredicate(root = BankTransactions.class) Predicate predicate,    
      Pageable pageable, @RequestParam MultiValueMap<String, String> parameters) {
    Page<BankTransactions> response = repository.findAll(predicate, pageable);
    return response;

}

答案 1 :(得分:1)

这是我的解决方案,使用QueryDslPredicateExecutor(允许执行Predicate)&amp; QueryDslBindings(允许路径特定绑定 - API)。

例如,如果我尝试查找&#34; FindMe&#34;使用&#34; ind&#34;或&#34; Ind&#34;它会在&#34; FindMe中正确返回两个实例中的结果。绑定不会被绑定在HTTPRequest的谓词上找不到。

public interface BankTransactionsRepository extends PagingAndSortingRepository<BankTransactions, Long>,                                             
QueryDslPredicateExecutor<BankTransactions>,                                                
QuerydslBinderCustomizer<QBankTransactions> {

  @Override
  default public void customize(QuerydslBindings bindings, 
                                QBankTransactions root) {
      bindings.bind(root.description).first((path, value) -> path.containsIgnoreCase(value));
      bindings.bind(root.template.code).first((path, value) -> path.containsIgnoreCase(value));
      bindings.bind(root.status).first((path, value) -> path.containsIgnoreCase(value));
      bindings.bind(root.processedDate).first((path, value) -> path.eq(value));
  }    
}

答案 2 :(得分:0)

我真的不喜欢这个答案,但至少它让我的代码看起来更干净。我为每种数据类型添加了辅助方法(eq)。

至少我的代码是每个输入鉴别器一行。

public Page<BankTransactions> get(
  @RequestParam(required = false) String bankAccountNumber,
  @RequestParam(required = false) String branchCode,
  Pageable pageable) {

  QBankTransactions q = QBankTransactions.bankTransactions;
  BooleanExpression expression = null;

  expression = eq(bankAccountNumber, expression, q.bankAccountNumber);
  expression = eq(branchCode, expression, q.branchCode);

  if (expression != null) {
    Page<BankTransactions> response = repository.findAll(expression, pageable);
    return response;
  } else {
    Page<BankTransactions> response = repository.findAll(pageable);
    return response;
  }
}

private BooleanExpression eq(String inputString, BooleanExpression expression, StringPath path) {
  if (inputString != null) {
    if (expression == null) {
      expression = path.eq(inputString);
    } else {
      expression.and(path.eq(inputString));
    }
  }
  return expression;
}

private BooleanExpression eq(Long inputLong, BooleanExpression expression, NumberPath path) {
  if (inputLong != null) {
    if (expression == null) {
      expression = path.eq(inputLong);
    } else {
      expression.and(path.eq(inputLong));
    }
  }
  return expression;
}