如何将Postgres row_to_json()生成的JSON反序列化为Jooq TableRecord?
将Postgres row_to_json()输出转换为Jooq TableRecord
问题场景
Postgres中存在InventoryItem表,建表语句如下:
CREATE TABLE "InventoryItem" ( "id" BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, "price_per_100_units" double precision, "weight_in_kilograms" double precision, "inventory_count" integer, "expected_value" double precision, "description" text );
通过row_to_json()函数生成的单条记录JSON格式如下:
{ "id": 6, "price_per_100_units": null, "weight_in_kilograms": null, "inventory_count": null, "expected_value": 142, "description": null }
尝试用Jooq自带的JSON导入功能转换为InventoryItemRecord实例失败,因为该功能仅支持Jooq自身导出的JSON格式。不想为每个表编写POJO再转Record,求高效转换方法。
解决方案
方法1:利用Postgres的json_populate_record函数直接查询转换
这是最简便的方案,借助Postgres内置函数将JSON直接还原为表行数据,再通过Jooq获取对应的Record:
// 假设已初始化DSLContext dsl String jsonStr = "{\"id\":6,\"price_per_100_units\":null,...}"; InventoryItemRecord record = dsl.fetchOne( "SELECT json_populate_record(null::\"InventoryItem\", ?)", SQL.JSON(jsonStr) ).into(InventoryItemRecord.class);
原理:json_populate_record会将JSON数据按照目标表的结构填充为行数据,Jooq可以直接将查询结果映射为对应的TableRecord。
方法2:自定义通用映射工具(基于Jackson)
如果不想依赖数据库查询,可通过Jackson解析JSON为Map,再批量赋值到Record中,适合多表通用:
import com.fasterxml.jackson.databind.ObjectMapper; import org.jooq.Record; import org.jooq.Table; import java.util.Map; public class JsonToRecordUtil { private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); @SuppressWarnings("unchecked") public static <R extends Record> R convert(String json, Table<R> table) throws Exception { R record = table.newRecord(); Map<String, Object> jsonMap = OBJECT_MAPPER.readValue(json, Map.class); table.fields().forEach(field -> { String fieldName = field.getName(); if (jsonMap.containsKey(fieldName)) { record.setValue(field, jsonMap.get(fieldName)); } }); return record; } } // 使用示例 InventoryItemRecord record = JsonToRecordUtil.convert(jsonStr, INVENTORY_ITEM);
该工具类可复用在所有TableRecord的转换场景,只需传入对应的Table对象和JSON字符串即可。
方法3:配置Jooq的JSON映射规则(进阶)
如果长期需要处理此类JSON格式,可以自定义Jooq的RecordMapper,覆盖默认的JSON解析逻辑,让Jooq直接支持row_to_json()的输出格式。不过该方案需要深入Jooq的映射体系,适合有定制化需求的场景。
内容的提问来源于stack exchange,提问作者J. Cool
相关产品推荐
相关产品推荐

