在JOOQ中动态建立条件

时间:2017-10-17 16:56:03

标签: java sql spring-boot jooq

我有一个端点,它接收一个字符串,其中包含要过滤的所有列和值。以下是过滤器参数的示例:?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);
}

1 个答案:

答案 0 :(得分:2)

更改对

的所有引用
condition.and(...)

为:

condition = condition.and(...)

Condition对象的值实际上没有更新。