You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在无json_object_keys方法的旧版JOOQ中提取jsonb键数组

提取JSONB字段所有键为数组的实现方案(旧版JOOQ)

针对旧版JOOQ无json_object_keys方法的情况,有两种可行方案:

方案一:直接调用PostgreSQL原生SQL函数

利用PostgreSQL本身支持的jsonb_object_keys和数组生成语法,通过JOOQ的DSL.field()直接嵌入原生SQL,在数据库端完成键提取和数组聚合:

单条记录提取键数组

// 假设表名为my_table,JSONB字段为data
Field<JSONB> keysArray = DSL.field(
    "ARRAY(SELECT jsonb_object_keys({0}))", 
    JSONB.class, 
    MY_TABLE.DATA
);

// 查询指定记录的键数组
JSONB resultKeys = ctx.select(keysArray)
    .from(MY_TABLE)
    .where(MY_TABLE.ID.eq(1L))
    .fetchOne()
    .value1();

批量提取所有记录的键数组

Result<Record2<Long, JSONB>> results = ctx.select(
        MY_TABLE.ID,
        DSL.field("ARRAY(SELECT jsonb_object_keys({0}))", JSONB.class, MY_TABLE.DATA)
    )
    .from(MY_TABLE)
    .fetch();

// 遍历结果
for (Record2<Long, JSONB> record : results) {
    Long id = record.value1();
    JSONB keysArray = record.value2();
    // 业务处理
}

这种方案性能更优,所有计算在数据库端完成,适合大数据量场景。

方案二:Java端解析JSONB字符串

先将JSONB字段转为字符串查询出来,再用JSON解析库(如Jackson、Gson)在Java端提取键并组装成数组:

// 查询JSONB字段的文本形式
Result<Record2<Long, String>> results = ctx.select(
        MY_TABLE.ID,
        MY_TABLE.DATA.cast(String.class)
    )
    .from(MY_TABLE)
    .fetch();

// 用Jackson解析提取键
ObjectMapper mapper = new ObjectMapper();
for (Record2<Long, String> record : results) {
    String jsonStr = record.value2();
    JsonNode jsonNode = mapper.readTree(jsonStr);
    
    // 提取所有键并转为数组
    List<String> keys = new ArrayList<>();
    Iterator<String> keyIterator = jsonNode.fieldNames();
    while (keyIterator.hasNext()) {
        keys.add(keyIterator.next());
    }
    JSONArray keysArray = new JSONArray(keys);
    
    // 业务处理
}

这种方案无需依赖数据库函数,灵活性高,但大数据量下会增加Java端的内存和计算压力,适合小数据量场景。

内容的提问来源于stack exchange,提问作者J.Doe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 21:30:45