Mybatisplus3.5.6,用String处理数据库列为JSONB字段

SQL建表语句:

复制代码
CREATE TABLE ts_data (
    device_sn varchar(300) NOT NULL,
    ts TIMESTAMPTZ NOT NULL,
    da JSONB NOT NULL,
    CONSTRAINT ts_data_pkey PRIMARY KEY (device_sn, ts, da)
);

数据库表Entity,这里字段da定义为String:

java 复制代码
@Data
@TableName("ts_data")
public class TsData {

    private String deviceSn;

    @TableField(value = "da", typeHandler = JsonbTypeHandler.class)
    private String da;

    @TableField("ts")  // 映射数据库中的TIMESTAMPTZ列
    private OffsetDateTime ts;

}

mybatis的自定义json处理器:

java 复制代码
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedTypes;
import org.postgresql.util.PGobject;

import java.lang.reflect.Field;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

@Slf4j
@MappedTypes({Object.class})
public class JsonbTypeHandler extends JacksonTypeHandler {

    public JsonbTypeHandler(Class<?> type) {
        super(type);
    }

    // 自3.5.6版本开始支持泛型.
    public JsonbTypeHandler(Class<?> type, Field field) {
        super(type, field);
    }

    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, Object parameter, JdbcType jdbcType) throws SQLException {
        if (ps != null) {
            PGobject jsonObject = new PGobject();
            jsonObject.setType("jsonb");
            jsonObject.setValue(toJson(parameter));
            ps.setObject(i, jsonObject);
        }
    }


    @Override
    public Object getNullableResult(ResultSet rs, String columnName) throws SQLException {
        String json = rs.getString(columnName);
        if (json == null || json.trim().isEmpty()) {
            return null;
        }

        try {
            // 调用父类的反序列化方法
            return super.getNullableResult(rs, columnName);
        } catch (Exception e) {
            log.warn("反序列化JSON字段 {} 失败,原始内容: {}", columnName, json, e);
            // 可选:返回原始字符串而非抛出异常
            return json;
        }
    }


}

mybatis的xml文件中配置部分,需要指定自定义处理器:

XML 复制代码
<resultMap id="ResultTsMap" type="com.demo.entity.TsData">
        <result column="sn" property="sn" />
        <result column="ts" property="ts"  />
        <result column="da" property="da" javaType="java.lang.String" typeHandler="com.demo.config.handler.JsonbTypeHandler" />
</resultMap>

Mapper类中的新增方法,需要指定为jsonb:

java 复制代码
@Mapper
public interface TsDataMapper extends BaseMapper<TsData> {
    
	@Insert("insert into ts_data(device_sn,da,ts)values(#{sn},#{da}::jsonb,#{ts})")
    int insert(String sn, String da, OffsetDateTime ts);
	
}

如上所示,在新增数据时,就可以将String格式的json字段插入到表中列格式为jsonb的字段。

查询时,将从数据库中查询到的字符串显示转换成json即可。

相关推荐
9523611 分钟前
Spring-cloud配置中心
java·spring·spring cloud·微服务
ydd10010022 分钟前
寻找两个正序数组的中位数 Java 题解,二分分割详解
java·开发语言
老纪的技术唠嗑局1 小时前
超级干货分享:中小企业使用 OceanBase 实践经验汇总
数据库
CLOUD ACE1 小时前
谷歌云代理|零售商Target 如何利用 Spanner Graph 提升零售发现体验并将数据库维护成本降低 50%
数据库·零售
真上帝的左手2 小时前
10. 软件设计&架构-Spring Security 7 整合CAS SSO 单点登录
java·spring·架构·sso
AI大模型-小雄2 小时前
Codex写分页接口为什么越翻越慢?用Cursor Pagination解决重复与漏数据
大数据·数据库·elasticsearch·搜索引擎·chatgpt·后端开发·codex
Zane19942 小时前
单例线程安全、生产者消费者、死锁:并发面试三连问串讲
java·后端
少晓年2 小时前
从 MySQL 迁移到人大金仓 KingbaseES:完整指南与实践
数据库·mysql
云烟成雨TD3 小时前
Micrometer 系列【42】链路追踪:Span 体系 | 核心 API
java·链路追踪·micrometer
SelectDB3 小时前
Apache Doris AI RAG 实战:从基础 RAG 到知识图谱增强的技术能力与选型
数据库