【PostgreSQL】Spring boot + Mybatis-plus + PostgreSQL 处理json类型情况
Spring boot + Mybatis-plus + PostgreSQL 处理json类型情况
- 一、前言
- 二、技术栈
- 三、背景分析
- 四、方案分析
- 4.1 在PostgreSQL 数据库中直接存储 json 对象
- 4.2 在PostgreSQL 数据库中存储 json 字符串
- 五、自定义类型处理器
- 5.1 定义类型处理器
- 5.2 使用自定义类型处理器
一、前言
在 Springboot 项目开发中,一般使用关系型数据库作为主库存储数据,有时候业务场景需要在既有的表结构上,扩展自定义业务信息。这种场景下一般使用json类型存储。本文总结 Springboot 项目中,借助 Mybatis-plus 操作json实践方案。
二、技术栈
Spring boot + Mybatis-plus + PostgreSQL,在 PostgreSQL 数据库中某一个字段为 json 类型。

三、背景分析
在 MyBatis 中,类型处理器(TypeHandler)扮演着 JavaType 与 JdbcType 之间转换的桥梁角色。它们用于在执行 SQL 语句时,将 Java 对象的值设置到 PreparedStatement 中,或者从 ResultSet 或 CallableStatement 中取出值。
MyBatis-Plus 给大家提供了提供了一些内置的类型处理器,可以通过 TableField 注解快速注入到 MyBatis 容器中,从而简化开发过程。MyBatis-Plus 字段类型处理器官方参考文档:字段类型处理器 | MyBatis-Plus (baomidou.com)
JSON 字段类型处理器
MyBatis-Plus 内置了多种 JSON 类型处理器,包括 AbstractJsonTypeHandler 及其子类 Fastjson2TypeHandler、FastjsonTypeHandler、GsonTypeHandler、JacksonTypeHandler 等。这些处理器可以将 JSON 字符串与 Java 对象相互转换。
四、方案分析
4.1 在PostgreSQL 数据库中直接存储 json 对象
PostgreSQL 数据库字段如上图所示:param_config 是一个 json 类型的字段。
步骤一:DO实体写法
字段数据类型为 com.alibaba.fastjson2.JSONObject 。
@Data
@Accessors(chain = true)
@TableName(autoResultMap = true)
public class User {private Long id;.../*** 关键代码!!!* 必须开启映射注解** @TableName(autoResultMap = true)** 选择对应的 JSON 处理器,并确保存在对应的 JSON 解析依赖包*/@TableField(value = "param_config", typeHandler = JacksonTypeHandler.class)// 或者使用 FastjsonTypeHandler// @TableField(typeHandler = FastjsonTypeHandler.class)private JSONObject paramConfig;
}
步骤二:XML 配置对应写法
<!-- 关键代码!!!!!!! -->
<!-- 单个字段的类型处理器配置 -->
<result column="param_config" jdbcType="VARCHAR" property="paramConfig" typeHandler="com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler" /><!-- 多个字段中某个字段的类型处理器配置 -->
<resultMap id="departmentResultMap" type="com.baomidou...DepartmentVO"><result property="director" column="director" typeHandler="com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler" />
</resultMap>
<select id="selectPageVO" resultMap="departmentResultMap">select id,name,director from department ...
</select>
查看保存在数据库中的结果,如下图所示:

4.2 在PostgreSQL 数据库中存储 json 字符串
先在 PostgreSQL 的数据库 URL 后面加上 &stringtype=unspecified,注意,如果此配置前面直接是数据库名字,则需要将 & 换成 ? 。
步骤一:DO实体类写法
@TableField(value = "param_config", typeHandler = JacksonTypeHandler.class)
private String paramConfig;
步骤二:XML 配置对应写法
<!-- 单个字段的类型处理器配置 -->
<result column="param_config" jdbcType="VARCHAR" property="paramConfig" typeHandler="com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler" />
查看保存在数据库中的结果,如下图所示:

五、自定义类型处理器
在 MyBatis-Plus 中,除了使用内置的类型处理器外,开发者还可以根据需要自定义类型处理器。
例如,当使用 PostgreSQL 数据库时,可能会遇到 JSON 类型的字段,这时可以创建一个自定义的类型处理器来处理 JSON 数据。
5.1 定义类型处理器
以下是一个自定义的 JSON 类型处理器的示例:
package com.ruoyi.common.utils.pg;import com.ruoyi.common.utils.StringUtils;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedTypes;
import org.postgresql.util.PGobject;import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;/*** @ClassName: JsonTypeHandlerPg* @Description: json对象处理* @Author: hjm* @Date: 2024-07-11 10:34*/
@MappedTypes(String.class)
public class JsonTypeHandlerPg extends BaseTypeHandler<String> {/*** 引入PGSQL提供的工具类PGobject*/private static final PGobject JSON_OBJECT = new PGobject();public static final String JSON_TYPE = "json";/*** 关键位置!!!*/@Overridepublic void setNonNullParameter(PreparedStatement ps, int i, String param, JdbcType jdbcType) throws SQLException {JSON_OBJECT.setType(JSON_TYPE);JSON_OBJECT.setValue(param);ps.setObject(i, JSON_OBJECT);}@Overridepublic String getNullableResult(ResultSet rs, String columnName) throws SQLException {String sqlJson = rs.getString(columnName);if (StringUtils.isNotBlank(sqlJson)) {return sqlJson;}return null;}// 根据列索引,获取可以为空的结果@Overridepublic String getNullableResult(ResultSet rs, int columnIndex) throws SQLException {String sqlJson = rs.getString(columnIndex);if (StringUtils.isNotBlank(sqlJson)) {return sqlJson;}return null;}@Overridepublic String getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {String sqlJson = cs.getString(columnIndex);if (StringUtils.isNotBlank(sqlJson)) {return sqlJson;}return null;}
}
5.2 使用自定义类型处理器
在实体类中,通过 TableField 注解指定自定义的类型处理器:
/*** 测试对象** @author hjm* @date 2024-07-11*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("data_test")
public class DataTest extends BaseEntity {private static final long serialVersionUID = 1L;/*** 主键*/@TableId(value = "id")private Long id;/*** 关键位置!!!*/@TableField(typeHandler = JsonTypeHandlerPg.class)private String jsonData;
}
修改mapper文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.dt.mapper.DataTestMapper"><resultMap type="com.ruoyi.dt.domain.DataTest" id="DataTestResult"><result property="id" column="id"/><!-- 关键位置!!! --><result property="jsonData" column="json_data" typeHandler="com.ruoyi.common.utils.pg.JsonTypeHandlerPg"/><result property="createBy" column="create_by"/><result property="createTime" column="create_time"/><result property="updateBy" column="update_by"/><result property="updateTime" column="update_time"/></resultMap></mapper>
业务代码
/*** 新增数据*/@Overridepublic Boolean insertByAo(DataTestAo ao) {DataTest add = BeanUtil.toBean(ao, DataTest.class);// 关键位置!!!add.setJsonData(JSONUtil.toJsonStr(ao));validEntityBeforeSave(add);boolean flag = baseMapper.insert(add) > 0;if (flag) {ao.setId(add.getId());}return flag;}
本文完结!
相关文章:
【PostgreSQL】Spring boot + Mybatis-plus + PostgreSQL 处理json类型情况
Spring boot Mybatis-plus PostgreSQL 处理json类型情况 一、前言二、技术栈三、背景分析四、方案分析4.1 在PostgreSQL 数据库中直接存储 json 对象4.2 在PostgreSQL 数据库中存储 json 字符串 五、自定义类型处理器5.1 定义类型处理器5.2 使用自定义类型处理器 一、前言 在…...
华为910b推理Qwen1.5-72b
前情提要:华为910b部署训练推理大模型,本人之前并没有接触过,所以,写此文档进行记录。 (注意:版本适配很重要!!不然就像我一样走了好多坑~~~) 首先,看一张图…...
legoloam算法环境配置和调试笔记
安装gtsam 参考 Ubuntu20.04安装gtsam记录_gtsam安装-CSDN博客 mkdir buildcd buildcmake .. make -...
如何用CSS3画一个三角形?
要用 CSS3 画一个三角形,可以利用元素的边框和透明边框的特性来实现。以下是一个简单的示例代码: .triangle {width: 0;height: 0;border-left: 50px solid transparent; /* 左边框为透明,控制三角形的左斜边 */border-right: 50px solid tr…...
不同型号的GD32 MCU如何区分?
大家是否碰到过以下应用场景:同一套软件代码希望跑在不同型号的GD32 MCU中,但有些地方需要根据MCU型号进行调整?或者上位机或其他MCU与GD32 MCU通信时需要知道对应的MCU型号是哪个? 此时,我们就需要了解如何获取以及区…...
关于windows下编译xLua插件的流程记录
1.工程准备 1.xLua工程:GitHub - Tencent/xLua: xLua is a lua programming solution for C# ( Unity, .Net, Mono) , it supports android, ios, windows, linux, osx, etc. 2.build_xlua_with_libs工程:GitHub - chexiongsheng/build_xlua_with_libs…...
Hadoop简明教程
文章目录 关于HadoopHadoop拓扑结构Namenode 和 Datanode 基本管理启动Hadoop启动YARN验证Hadoop服务停止Hadoop停止HDFS Hadoop集群搭建步骤准备阶段Java环境配置Hadoop安装与配置HDFS格式化与启动服务测试集群安装额外组件监控与维护: 使用Docker搭建集群使用Hado…...
基于STM32设计的药品柜温湿度监测系统(华为云IOT)(184)
基于STM32设计的药品柜温湿度监测系统(华为云IOT)(184) 文章目录 一、前言1.1 项目介绍【1】项目功能介绍【2】整体需求总结【3】项目硬件模块组成1.2 设计思路【1】整体设计思路【2】ESP8266工作模式配置【3】华为云IOT手机APP界面开发思路1.3 项目开发背景【1】选题的意义【2…...
SpringBoot源码阅读(10)——后处理器
后处理器是在监听器EnvironmentPostProcessorApplicationListener中被加载。 入口在SpringApplication实例方法prepareEnvironment,第343行。 listeners.environmentPrepared(bootstrapContext, environment);这里触发了事件ApplicationEnvironmentPreparedEvent 相…...
【源码开源】C#桌面应用开发:串口调试助手
c#桌面应用开发 1、环境搭建和工程创建:参照番茄定时器项目 工程创建参照 2、界面布局设计 3、具体功能函数 (1)端口扫描: private void btn_com_scan_Click(object sender, EventArgs e){//端口号扫描ReflashPortToComboBox(…...
malloc与free函数的用法(精简全面 · 一看即懂)
前言:Hello大家好😘,我是心跳sy,今天为大家带来malloc函数与free函数的用法,我们一起来看看吧! 目录 一、malloc函数 💫 1、⭐️malloc函数对应的头文件⭐️ 2、⭐️malloc函数的作用⭐️ 3…...
强制升级最新系统,微软全面淘汰Win10和部分11用户
说出来可能不信,距离 Windows 11 正式发布已过去整整三年时间,按理说现在怎么也得人均 Win 11 水平了吧? 然而事实却是,三年时间过去 Win 11 占有率仅仅突破到 29%,也就跳起来摸 Win 10 屁股的程度。 2024 年 6 月 Wi…...
java-命令行连接 mysql
在 Java 中,通过命令行连接 MySQL 可以使用以下步骤。假设您已经安装并配置了 MySQL 5.7。 ### 一、通过命令行连接 MySQL #### 1. 打开命令行终端 在不同的操作系统上打开命令行终端的方式: - **Windows**:按 Win R 键,输入…...
RK3588部署YOLOV8-seg的问题
在使用YOLOV8-seg训练出来的pt模型转为onnx的时候,利用以下仓库地址转。 git clone https://github.com/airockchip/ultralytics_yolov8.git 在修改ultralytics/cfg/default.yaml中的task,mode为model为自己需要的内容后, 执行以下语句 cd …...
Python Linux下编译
注意 本教程针对较新Linux系统,没有升级依赖、处理旧版本Linux的openssl等步骤,如有需要可以查看往期文章,例如:在Centos7.6镜像中安装Python3.9 教程中没有使用默认位置、默认可执行文件名,请注意甄别 安装路径&#…...
SpringMVC(3)——SpringMVC注解实战
前言 SpringMVC(2)——controller方法参数与html表单对应(请求参数的绑定) 上篇博客我们提到了controller方法的参数与html表单之间的对应关系 但是这种对应关系有很多缺点: 传递参数只能放在request的body当中&am…...
统信UOS上批量安装惠普打印驱动后启动器没有图标的解决方法
原文链接:统信UOS上批量安装惠普打印驱动后启动器没有图标的解决方法 Hello,大家好啊!今天给大家带来一篇关于在统信UOS上批量安装惠普打印驱动后启动器没有设置图标的解决方法的文章。批量安装打印驱动是企业和个人用户常见的操作࿰…...
Python UDP编程之实时聊天与网络监控详解
概要 UDP(User Datagram Protocol,用户数据报协议)是网络协议中的一种,主要用于快速、简单的通信场景。与TCP相比,UDP没有连接、确认、重传等机制,因此传输效率高,但也不保证数据的可靠性和顺序。本文将详细介绍Python中如何使用UDP协议进行网络通信,并包含相应的示例…...
LiveNVR监控流媒体Onvif/RTSP用户手册-用户管理:编辑、添加用户、关联通道、重置密码、删除、过滤搜索
LiveNVR监控流媒体Onvif/RTSP用户手册-用户管理:编辑、添加用户、关联通道、重置密码、删除、过滤搜索 1、用户管理1.1、添加用户1.2、关联通道1.3、重置密码1.4、编辑1.5、删除1.6、过滤搜索 2、RTSP/HLS/FLV/RTMP拉流Onvif流媒体服务 1、用户管理 1.1、添加用户 点击用户管理…...
SpringBoot新手快速入门系列教程十:基于Docker Compose,部署一个简单的项目
前述: 本篇教程将略过很多docker下载环境配置的基础步骤,如果您对docker不太熟悉请参考我的上一个教程:SpringBoot新手快速入门系列教程九:基于docker容器,部署一个简单的项目 使用 Docker Compose 支持部署 Docker 项…...
MPNet:旋转机械轻量化故障诊断模型详解python代码复现
目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...
Android Wi-Fi 连接失败日志分析
1. Android wifi 关键日志总结 (1) Wi-Fi 断开 (CTRL-EVENT-DISCONNECTED reason3) 日志相关部分: 06-05 10:48:40.987 943 943 I wpa_supplicant: wlan0: CTRL-EVENT-DISCONNECTED bssid44:9b:c1:57:a8:90 reason3 locally_generated1解析: CTR…...
基于uniapp+WebSocket实现聊天对话、消息监听、消息推送、聊天室等功能,多端兼容
基于 UniApp + WebSocket实现多端兼容的实时通讯系统,涵盖WebSocket连接建立、消息收发机制、多端兼容性配置、消息实时监听等功能,适配微信小程序、H5、Android、iOS等终端 目录 技术选型分析WebSocket协议优势UniApp跨平台特性WebSocket 基础实现连接管理消息收发连接…...
【项目实战】通过多模态+LangGraph实现PPT生成助手
PPT自动生成系统 基于LangGraph的PPT自动生成系统,可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析:自动解析Markdown文档结构PPT模板分析:分析PPT模板的布局和风格智能布局决策:匹配内容与合适的PPT布局自动…...
TRS收益互换:跨境资本流动的金融创新工具与系统化解决方案
一、TRS收益互换的本质与业务逻辑 (一)概念解析 TRS(Total Return Swap)收益互换是一种金融衍生工具,指交易双方约定在未来一定期限内,基于特定资产或指数的表现进行现金流交换的协议。其核心特征包括&am…...
LangFlow技术架构分析
🔧 LangFlow 的可视化技术栈 前端节点编辑器 底层框架:基于 (一个现代化的 React 节点绘图库) 功能: 拖拽式构建 LangGraph 状态机 实时连线定义节点依赖关系 可视化调试循环和分支逻辑 与 LangGraph 的深…...
pycharm 设置环境出错
pycharm 设置环境出错 pycharm 新建项目,设置虚拟环境,出错 pycharm 出错 Cannot open Local Failed to start [powershell.exe, -NoExit, -ExecutionPolicy, Bypass, -File, C:\Program Files\JetBrains\PyCharm 2024.1.3\plugins\terminal\shell-int…...
[论文阅读]TrustRAG: Enhancing Robustness and Trustworthiness in RAG
TrustRAG: Enhancing Robustness and Trustworthiness in RAG [2501.00879] TrustRAG: Enhancing Robustness and Trustworthiness in Retrieval-Augmented Generation 代码:HuichiZhou/TrustRAG: Code for "TrustRAG: Enhancing Robustness and Trustworthin…...
前端调试HTTP状态码
1xx(信息类状态码) 这类状态码表示临时响应,需要客户端继续处理请求。 100 Continue 服务器已收到请求的初始部分,客户端应继续发送剩余部分。 2xx(成功类状态码) 表示请求已成功被服务器接收、理解并处…...
Django RBAC项目后端实战 - 03 DRF权限控制实现
项目背景 在上一篇文章中,我们完成了JWT认证系统的集成。本篇文章将实现基于Redis的RBAC权限控制系统,为系统提供细粒度的权限控制。 开发目标 实现基于Redis的权限缓存机制开发DRF权限控制类实现权限管理API配置权限白名单 前置配置 在开始开发权限…...
