【问题标题】:Dynamically building conditions in JOOQ在 JOOQ 中动态构建条件
【发布时间】:2018-03-29 10:52:49
【问题描述】:

我有一个端点,它接收一个字符串,其中包含他们想要过滤的所有列和值。这是过滤器参数的示例:?filter=active=true,type=ADMIN,基本上每个过滤器都由,分隔,然后列名和过滤器值由=分隔所以我用这个方法来动态构建条件具有任何表的所有不同过滤器的语句:

public Condition mapFilterToCondition(String tableName, String filters) {
    Condition condition = DSL.trueCondition();
    String[] filterFields = filters.split(",");
    Table<?> table = PUBLIC.getTable(tableName);
    Field<?>[] fields = table.fields();
    for(String filterField : filterFields) {
        String[] filter = filterField.split("=");
        for(Field<?> field : fields) {
            String fieldName = CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, filter[0]);
            if(field.getName().equals(fieldName)) {
                if(field.getType() == String.class) {
                    condition.and(table.field(field).like(filter[1]));
                } else if (Boolean.valueOf(filter[1])) {
                    condition.and(table.field(field).isTrue());
                } else if (!Boolean.valueOf(filter[1])) {
                    condition.and(table.field(field).isFalse());
                }
            }
        }
    }
    return condition;
}

然后我使用此方法构建的条件来调用发出 sql 请求的存储库:

public List<UserAccount> findAllByFilter(Condition condition, Pageable pageable) {
    return dsl.select()
            .from(USER_ACCOUNT)
            .where(condition)
            .limit(pageable.getPageSize())
            .offset((int) pageable.getOffset())
            .fetchInto(UserAccount.class);
}

据我了解,条件应该是这样的:

.where(USER_ACCOUNT.TYPE.like("ADMIN")) .where(USER_ACCOUNT.ACTIVE.isTrue())

基于我建立的条件,但每当我进行调用时,它都会返回每个用户,而不考虑过滤器。在调试时,我发现条件从未从1 = 1 改变,这是它从DSL.trueCondition(); 获得的值,所以我的问题是我应该如何处理这个条件的构造?我是在使用 condition.and(...) 错误,还是应该使用其他东西?

感谢任何帮助!

编辑

@GetMapping(value = "/admin", produces = "application/json")
public ResponseEntity listAll(String filters, Pageable pageable) {
    Condition condition = filterMapService.mapFilterToCondition("user_account", filters);
    List<UserAccount> adminAccounts = userAccountRepository.findAllByFilter(condition, pageable);
    if (adminAccounts.isEmpty()) {
        return new ResponseEntity(HttpStatus.NO_CONTENT);
    }
    List<AdminDTO> accounts = adminAccounts.stream()
            .map(account -> modelMapper.map(account, AdminDTO.class)).collect(Collectors.toList());
    return new ResponseEntity<>(accounts, HttpStatus.OK);
}

【问题讨论】:

  • 您提供的示例 filter=active=true,type=ADMIN 似乎格式不正确。你能提供你提供的其他输入吗?
  • 格式不正确是什么意思?
  • 您是否将字符串:“filter=active=true, type=ADMIN”提供给您的方法mapFilterToCondition
  • 我已经用调用方法的控制器编辑了问题。 filters 变量是一个请求参数,但我很确定问题与条件部分有关。
  • 如果没有添加条件,那么问题很可能来自String fieldName = CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, filter[0]); if(field.getName().equals(fieldName)) 行。确保表中的字段与上面第一行设置的字段名称匹配。 (我不熟悉您使用的框架,但 field.getName() 可能会返回例如大写字符串。

标签: java sql spring-boot jooq


【解决方案1】:

将所有引用更改为

condition.and(...)

到:

condition = condition.and(...)

Condition 对象的值实际上并未得到更新。

【讨论】:

猜你喜欢
  • 2018-04-09
  • 2018-10-05
  • 1970-01-01
  • 1970-01-01
  • 2016-06-08
  • 2013-10-06
  • 2019-09-02
  • 1970-01-01
  • 2012-12-12
相关资源
最近更新 更多