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

使用JOOQ更新PostgreSQL的JSONB字段值报语法错误如何解决?

问题根因

你遇到的语法错误核心原因是:jOOQ 的 Plain SQL 模板语法中,{} 会被识别为参数占位标记,你直接将带大括号的JSON字符串写在field()方法的第一个参数中时,JSON的外层大括号被jOOQ解析为模板标记,导致最终生成的SQL丢失了JSON的外层结构和引号,触发PostgreSQL语法错误。

解决方案

方案1:转义模板大括号(仅适合临时硬编码场景)

在Plain SQL模板中,要输出字面量的{、}需要用双大括号{{、}}转义,修改后的代码如下:

DSL.using(connection).update(USER_SETTINGS)
        .set(USER_SETTINGS.SETTING_VALUE, field("{{\"filtersValue\":{{\"page\":0,\"size\":100}}, \"visibleCount\":100}}", JSONB.class))
        .where(USER_SETTINGS.USER_ID.eq(98383L))
        .execute();

方案2:使用DSL.val()绑定参数(更推荐,安全无转义问题)

直接将JSON字符串作为值绑定,jOOQ会自动处理类型转换,不需要处理转义,也避免SQL注入风险:

String jsonContent = "{\"filtersValue\":{\"page\":0,\"size\":100}, \"visibleCount\":100}";
DSL.using(connection).update(USER_SETTINGS)
        .set(USER_SETTINGS.SETTING_VALUE, DSL.val(jsonContent, JSONB.class))
        .where(USER_SETTINGS.USER_ID.eq(98383L))
        .execute();

方案3:Java对象序列化写入(适合复杂JSON场景,易维护)

如果JSON结构复杂,建议先定义对应的Java实体类,用JSON序列化工具(比如Jackson)转成字符串后再写入,避免手动拼接JSON出错:

// 定义配置实体类
public class FiltersValue {
    private Integer page;
    private Integer size;
    // 省略getter、setter
}
public class SettingValue {
    private FiltersValue filtersValue;
    private Integer visibleCount;
    // 省略getter、setter
}

// 序列化后写入
ObjectMapper objectMapper = new ObjectMapper();
FiltersValue filters = new FiltersValue();
filters.setPage(0);
filters.setSize(100);
SettingValue setting = new SettingValue();
setting.setFiltersValue(filters);
setting.setVisibleCount(100);
String jsonStr = objectMapper.writeValueAsString(setting);

DSL.using(connection).update(USER_SETTINGS)
        .set(USER_SETTINGS.SETTING_VALUE, DSL.val(jsonStr, JSONB.class))
        .where(USER_SETTINGS.USER_ID.eq(98383L))
        .execute();

内容的提问来源于stack exchange,提问作者Oleksii Hlovatskyi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 00:06:04