Files
workpod/dev-envs/flux/docs/Redkale使用易错点.md
T

9.7 KiB
Raw Blame History

Redkale FilterNode 使用易错点

创建时间:2026-02-03 基于:flux-api 项目实际代码


常见错误

1. LIKE 查询错误

错误写法

// ❌ 错误:使用静态方法
node.and(PartnerFormRecord::getRealname, FilterNode.like(keyword));

正确写法

// ✅ 正确:使用实例方法
node.like(PartnerFormRecord::getRealname, keyword);

2. 比较查询错误

错误写法

// ❌ 错误:方法名拼写错误
node.and(PartnerFormRecord::getCreatedtime, FilterNode.greateEqual(starttime));
node.and(PartnerFormRecord::getCreatedtime, FilterNode.lessEqual(endtime));

正确写法

// ✅ 正确:使用简短的方法名
node.ge(PartnerFormRecord::getCreatedtime, starttime);
node.le(PartnerFormRecord::getCreatedtime, endtime);

参考方法

  • ge() - Greater or Equal>=
  • le() - Less or Equal<=
  • gt() - Greater Than>
  • lt() - Less Than<

3. OR 条件错误

错误写法

// ❌ 错误:在 and() 中混用 FilterNode 静态方法
node.and(
    FilterNode.or(
        PartnerFormRecord::getRealname, FilterNode.like(keyword),
        PartnerFormRecord::getMobile, FilterNode.like(keyword)
    )
);

正确写法

// ✅ 正确:创建独立 OR 节点,链式调用
FilterNode orNode = new FilterNode();
orNode.or(PartnerFormRecord::getRealname, FilterNode.like(keyword))
      .or(PartnerFormRecord::getMobile, FilterNode.like(keyword))
      .or(PartnerFormRecord::getIdcard, FilterNode.like(keyword));
node.and(orNode);

4. 等值条件冗余

错误写法

// ❌ 冗余:等值条件不需要特殊方法
node.and(PartnerFormRecord::getStatus, FilterNode.eq(1));

正确写法

// ✅ 简洁:直接传值
node.and(PartnerFormRecord::getStatus, 1);

5. NOT 条件错误

错误写法

// ❌ 错误:使用不存在的 notLike 方法
node.notLike(PartnerFormRecord::getStatus, 3);

正确写法

// ✅ 正确:使用 notEq
node.notEq(PartnerFormRecord::getStatus, 3);

正确的模式

基础查询条件

FilterNode node = new FilterNode();

// 固定条件
node.and(PartnerFormRecord::getDraftstatus, (short) 0);

// 可选条件
if (bean.getKeyword() != null && !bean.getKeyword().isEmpty()) {
    node.like(PartnerFormRecord::getRealname, bean.getKeyword());
}

// 范围查询
if (bean.getStarttime() > 0) {
    node.ge(PartnerFormRecord::getCreatedtime, bean.getStarttime());
}
if (bean.getEndtime() > 0) {
    node.le(PartnerFormRecord::getCreatedtime, bean.getEndtime());
}

// 不等于
node.notEq(PartnerFormRecord::getStatus, (short) 3);

OR 条件组合

// 关键词:姓名 OR 电话 OR 身份证
if (bean.getKeyword() != null && !bean.getKeyword().isEmpty()) {
    FilterNode orNode = new FilterNode();
    orNode.or(PartnerFormRecord::getRealname, FilterNode.like(bean.getKeyword()))
          .or(PartnerFormRecord::getMobile, FilterNode.like(bean.getKeyword()))
          .or(PartnerFormRecord::getIdcard, FilterNode.like(bean.getKeyword()));
    node.and(orNode);
}

IN 条件

// IN 查询
FilterNode node = new FilterNode();
node.in(PartnerFormRecord::getFormdataid, formIds.toArray());
List<PartnerFormRecord> list = dataSource.queryList(PartnerFormRecord.class, node);

📋 FilterNode 方法速查表

方法 说明 示例
and() AND 等值条件 node.and(Entity::getField, value)
like() LIKE 模糊查询 node.like(Entity::getField, "%keyword%")
ge() >= 大于等于 node.ge(Entity::getTime, timestamp)
le() <= 小于等于 node.le(Entity::getTime, timestamp)
gt() > 大于 node.gt(Entity::getField, value)
lt() < 小于 node.lt(Entity::getField, value)
notEq() != 不等于 node.notEq(Entity::getStatus, 3)
in() IN 查询 node.in(Entity::getId, ids.toArray())
or() OR 条件 需创建独立 FilterNode

🔍 完整示例参考

PartnerFormService.java

@RestMapping(name = "list", comment = "分页查询表单记录")
public RetResult<Sheet<PartnerFormRecord>> list(FormRecordFilterBean bean, Flipper flipper) {
    FilterNode node = new FilterNode();
    node.notEq(PartnerFormRecord::getStatus, STATUS_DELETED);

    if (!Utils.isEmpty(bean.getRealname())) {
        node.like(PartnerFormRecord::getRealname, bean.getRealname());
    }
    if (bean.getDraftstatus() >= 0) {
        node.and(PartnerFormRecord::getDraftstatus, bean.getDraftstatus());
    }
    if (bean.getStarttime() > 0) {
        node.ge(PartnerFormRecord::getCreatedtime, bean.getStarttime());
    }
    if (bean.getEndtime() > 0) {
        node.le(PartnerFormRecord::getCreatedtime, bean.getEndtime());
    }

    Sheet<PartnerFormRecord> sheet = dataSource.querySheet(PartnerFormRecord.class, flipper, node);
    return render(sheet);
}

PartnerCustomerService.java

@RestMapping(name = "list", comment = "分页查询客户列表")
public RetResult<Sheet<PartnerCustomer>> list(PartnerCustomerFilterBean bean, Flipper flipper) {
    FilterNode node = new FilterNode();
    node.notEq(PartnerCustomer::getStatus, (short) 3);

    if (!Utils.isEmpty(bean.getMobile())) {
        node.and(PartnerCustomer::getMobile, bean.getMobile());
    }
    if (bean.getStatus() > 0) {
        node.and(PartnerCustomer::getStatus, bean.getStatus());
    }
    if (bean.getStarttime() > 0) {
        node.ge(PartnerCustomer::getCreatedtime, bean.getStarttime());
    }
    if (bean.getEndtime() > 0) {
        node.le(PartnerCustomer::getCreatedtime, bean.getEndtime());
    }

    Sheet<PartnerCustomer> sheet = dataSource.querySheet(PartnerCustomer.class, flipper, node);
    return render(sheet);
}

⚠️ 注意事项

  1. 方法调用方式:所有条件方法都是 FilterNode 实例的方法,不是静态方法
  2. 方法命名ge/le 而非 greateEqual/lessEqual
  3. OR 条件:必须创建独立的 FilterNode 对象进行链式调用
  4. 值比较:等值条件直接传值,不需要 FilterNode.eq()
  5. LIKE 参数:通常需要在参数中自行添加 % 通配符

📚 参考代码位置

  • flux-api/src/main/java/cn/casehub/partner/PartnerFormService.java
  • flux-api/src/main/java/cn/casehub/partner/PartnerCustomerService.java
  • flux-api/src/main/java/cn/casehub/partner/PartnerVisitService.java

Redkale JSON 使用要点

更新时间:2026-03-03 背景:速贷接口接入时错误使用 @JsonPropertyJackson 注解),Redkale 不支持


常见错误

1. 使用 Jackson 注解

错误写法

// ❌ 错误:Redkale 不支持 Jackson 注解
import com.fasterxml.jackson.annotation.JsonProperty;

@JsonProperty("mobile_md5")
private String mobileMd5;

正确方案:使用 Redkale 的 @ConvertColumn(name = "xxx") 进行字段重命名:

// ✅ 正确:使用 @ConvertColumn 重命名
import org.redkale.convert.ConvertColumn;

@ConvertColumn(name = "mobile_md5")
private String mobileMd5;  // Java驼峰,JSON下划线

JsonConvert 使用方式

序列化(对象 → JSON

// 方式1:实例方法
JsonConvert convert = JsonConvert.root();
String json = convert.convertTo(object);

// 方式2:静态调用
String json = JsonConvert.root().convertTo(object);

反序列化(JSON → 对象)

// 单个对象
User user = JsonConvert.root().convertFrom(User.class, json);

// 泛型集合
List<User> users = JsonConvert.root().convertFrom(
    new TypeToken<List<User>>() {}.getType(),
    json
);

// Map(用于解析不确定结构的JSON)
Map<String, Object> map = JsonConvert.root().convertFrom(Map.class, json);

📋 字段映射规则

Java 字段名 JSON 字段名 说明
mobileMd5 mobileMd5 默认:驼峰 → 驼峰
mobile_md5 mobile_md5 默认:下划线 → 下划线
mobileMd5 + @ConvertColumn(name="mobile_md5") mobile_md5 重命名
mobileMd5 + @ConvertColumn(ignore=true) - 忽略字段

结论:使用 @ConvertColumn(name = "xxx") 可实现字段重命名。


🔧 跨命名风格转换方案

当第三方接口使用下划线,内部使用驼峰时:

方案1@ConvertColumn + Utils.copy(推荐)

// 速贷请求BeanJava驼峰,JSON下划线)
public class SuDaiRequest {
    @ConvertColumn(name = "mobile_md5")
    private String mobileMd5;

    @ConvertColumn(name = "city_id")
    private String cityId;
}

// 内部Bean(驼峰)
public class CollideBean {
    private String mobileMd5;
    private String cityId;
}

// 转换器 - 使用 Utils.copy
public class Converter {
    public static CollideBean toBean(SuDaiRequest req) {
        return Utils.copy(new CollideBean(), req);  // 一行搞定
    }
}

方案2:手动映射(不推荐)

// 速贷请求Bean(下划线)
public class SuDaiRequest {
    private String mobile_md5;
    private String city_id;
}

// 转换器 - 手动映射
public class Converter {
    public static CollideBean toBean(SuDaiRequest req) {
        CollideBean bean = new CollideBean();
        bean.setMobileMd5(req.getMobile_md5());  // 手动映射
        bean.setCityId(req.getCity_id());
        return bean;
    }
}

⚠️ 注意事项

  1. 使用 @ConvertColumn:Redkale 的字段重命名注解,不是 Jackson 的 @JsonProperty
  2. @ConvertColumn 用法
    • @ConvertColumn(name = "xxx") - 重命名JSON字段
    • @ConvertColumn(ignore = true) - 忽略字段
  3. 配合 Utils.copy:重命名后,Java字段名一致,可用 Utils.copy 简化转换