当前位置: 首页 > news >正文

【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 及其子类 Fastjson2TypeHandlerFastjsonTypeHandlerGsonTypeHandlerJacksonTypeHandler 等。这些处理器可以将 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

前情提要&#xff1a;华为910b部署训练推理大模型&#xff0c;本人之前并没有接触过&#xff0c;所以&#xff0c;写此文档进行记录。 &#xff08;注意&#xff1a;版本适配很重要&#xff01;&#xff01;不然就像我一样走了好多坑~~~&#xff09; 首先&#xff0c;看一张图…...

legoloam算法环境配置和调试笔记

安装gtsam 参考 Ubuntu20.04安装gtsam记录_gtsam安装-CSDN博客 mkdir buildcd buildcmake .. make -...

如何用CSS3画一个三角形?

要用 CSS3 画一个三角形&#xff0c;可以利用元素的边框和透明边框的特性来实现。以下是一个简单的示例代码&#xff1a; .triangle {width: 0;height: 0;border-left: 50px solid transparent; /* 左边框为透明&#xff0c;控制三角形的左斜边 */border-right: 50px solid tr…...

不同型号的GD32 MCU如何区分?

大家是否碰到过以下应用场景&#xff1a;同一套软件代码希望跑在不同型号的GD32 MCU中&#xff0c;但有些地方需要根据MCU型号进行调整&#xff1f;或者上位机或其他MCU与GD32 MCU通信时需要知道对应的MCU型号是哪个&#xff1f; 此时&#xff0c;我们就需要了解如何获取以及区…...

关于windows下编译xLua插件的流程记录

1.工程准备 1.xLua工程&#xff1a;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工程&#xff1a;GitHub - chexiongsheng/build_xlua_with_libs…...

Hadoop简明教程

文章目录 关于HadoopHadoop拓扑结构Namenode 和 Datanode 基本管理启动Hadoop启动YARN验证Hadoop服务停止Hadoop停止HDFS Hadoop集群搭建步骤准备阶段Java环境配置Hadoop安装与配置HDFS格式化与启动服务测试集群安装额外组件监控与维护&#xff1a; 使用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&#xff0c;第343行。 listeners.environmentPrepared(bootstrapContext, environment);这里触发了事件ApplicationEnvironmentPreparedEvent 相…...

【源码开源】C#桌面应用开发:串口调试助手

c#桌面应用开发 1、环境搭建和工程创建&#xff1a;参照番茄定时器项目 工程创建参照 2、界面布局设计 3、具体功能函数 &#xff08;1&#xff09;端口扫描&#xff1a; private void btn_com_scan_Click(object sender, EventArgs e){//端口号扫描ReflashPortToComboBox(…...

malloc与free函数的用法(精简全面 · 一看即懂)

前言&#xff1a;Hello大家好&#x1f618;&#xff0c;我是心跳sy&#xff0c;今天为大家带来malloc函数与free函数的用法&#xff0c;我们一起来看看吧&#xff01; 目录 一、malloc函数 &#x1f4ab; 1、⭐️malloc函数对应的头文件⭐️ 2、⭐️malloc函数的作用⭐️ 3…...

强制升级最新系统,微软全面淘汰Win10和部分11用户

说出来可能不信&#xff0c;距离 Windows 11 正式发布已过去整整三年时间&#xff0c;按理说现在怎么也得人均 Win 11 水平了吧&#xff1f; 然而事实却是&#xff0c;三年时间过去 Win 11 占有率仅仅突破到 29%&#xff0c;也就跳起来摸 Win 10 屁股的程度。 2024 年 6 月 Wi…...

java-命令行连接 mysql

在 Java 中&#xff0c;通过命令行连接 MySQL 可以使用以下步骤。假设您已经安装并配置了 MySQL 5.7。 ### 一、通过命令行连接 MySQL #### 1. 打开命令行终端 在不同的操作系统上打开命令行终端的方式&#xff1a; - **Windows**&#xff1a;按 Win R 键&#xff0c;输入…...

RK3588部署YOLOV8-seg的问题

在使用YOLOV8-seg训练出来的pt模型转为onnx的时候&#xff0c;利用以下仓库地址转。 git clone https://github.com/airockchip/ultralytics_yolov8.git 在修改ultralytics/cfg/default.yaml中的task&#xff0c;mode为model为自己需要的内容后&#xff0c; 执行以下语句 cd …...

Python Linux下编译

注意 本教程针对较新Linux系统&#xff0c;没有升级依赖、处理旧版本Linux的openssl等步骤&#xff0c;如有需要可以查看往期文章&#xff0c;例如&#xff1a;在Centos7.6镜像中安装Python3.9 教程中没有使用默认位置、默认可执行文件名&#xff0c;请注意甄别 安装路径&#…...

SpringMVC(3)——SpringMVC注解实战

前言 SpringMVC&#xff08;2&#xff09;——controller方法参数与html表单对应&#xff08;请求参数的绑定&#xff09; 上篇博客我们提到了controller方法的参数与html表单之间的对应关系 但是这种对应关系有很多缺点&#xff1a; 传递参数只能放在request的body当中&am…...

统信UOS上批量安装惠普打印驱动后启动器没有图标的解决方法

原文链接&#xff1a;统信UOS上批量安装惠普打印驱动后启动器没有图标的解决方法 Hello&#xff0c;大家好啊&#xff01;今天给大家带来一篇关于在统信UOS上批量安装惠普打印驱动后启动器没有设置图标的解决方法的文章。批量安装打印驱动是企业和个人用户常见的操作&#xff0…...

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,部署一个简单的项目

前述&#xff1a; 本篇教程将略过很多docker下载环境配置的基础步骤&#xff0c;如果您对docker不太熟悉请参考我的上一个教程&#xff1a;SpringBoot新手快速入门系列教程九&#xff1a;基于docker容器&#xff0c;部署一个简单的项目 使用 Docker Compose 支持部署 Docker 项…...

Pixel Aurora Engine应用场景:独立开发者低成本构建像素IP资产库

Pixel Aurora Engine应用场景&#xff1a;独立开发者低成本构建像素IP资产库 1. 像素艺术创作新纪元 在游戏开发领域&#xff0c;像素艺术始终保持着独特的魅力。从早期的《超级马里奥》到现代的《星露谷物语》&#xff0c;像素风格游戏凭借其怀旧感和艺术表现力&#xff0c;…...

JeecgBoot启动配置

一、引入maven指定自己的maven仓库 二、指定JDK 记得apply&#xff01;&#xff01;&#xff01;&#xff01;然后OK 三、配置MySQL数据库(尽量≥5.7版本) 四、运行db文件夹下的SQL文件 五、后端本地环境&#xff08;application-dev.yml&#xff09;指定好数据源 1、M…...

当SPC焕发新生:云质信息重构制造质量管理新范式

传统SPC&#xff1a;那些让人头疼的“老毛病”说实话&#xff0c;很多企业斥巨资引入的SPC软件&#xff0c;实际使用体验与高级版Excel相差无几。数据需手动导入&#xff0c;图表需逐一点选生成&#xff0c;想要进行跨维度分析&#xff0c;更是要先将数据导出&#xff0c;借助其…...

嵌入式系统电源时序控制原理与实现

1. 电源时序控制基础概念在现代电子系统中&#xff0c;多电压域设计已成为常态。一个典型的嵌入式系统可能同时需要1.2V&#xff08;核心逻辑&#xff09;、3.3V&#xff08;外设接口&#xff09;和1.5V&#xff08;特殊功能模块&#xff09;等多种电压。这些电源的上电顺序对系…...

Arduino嵌入式SD卡逐行读取库ReadLines详解

1. 项目概述ReadLines 是一个专为 Arduino 平台设计的轻量级文件行读取库&#xff0c;核心目标是解决嵌入式系统中对 SD 卡文本文件进行逐行解析这一高频但易出错的操作需求。在资源受限的 MCU 环境下&#xff08;如 ESP8266、STM32F103C8T6、ATmega328P&#xff09;&#xff0…...

S2-Pro模型推理服务高可用部署:基于Docker与Kubernetes的架构

S2-Pro模型推理服务高可用部署&#xff1a;基于Docker与Kubernetes的架构 1. 为什么需要高可用部署 在实际生产环境中&#xff0c;AI模型推理服务的稳定性直接影响业务连续性。想象一下&#xff0c;当你的电商平台正在举行大促活动&#xff0c;AI推荐系统突然宕机&#xff0c…...

请解释 Linux 系统中的内核模块管理,并描述如何加载和卸载模块。

在 Linux 系统中&#xff0c;内核模块&#xff08;Kernel Modules&#xff09; 是可以在不重新编译或重启内核的情况下&#xff0c;动态添加到运行中内核的代码片段。它们通常用于支持新的硬件设备、文件系统或网络协议。 这种机制使得 Linux 内核保持精简&#xff08;核心功能…...

杨立昆新模型杀疯了,1500万参数单GPU就能碾压大厂?

就在前几天&#xff0c;AI教父、图灵奖得主杨立昆刚发了个新模型&#xff0c;名叫LeWorldModel&#xff0c;论文一发出&#xff0c;整个圈子瞬间炸锅。说出来你们可能都不信——这货只有1500万参数&#xff0c;单块GPU几个小时就能训完&#xff0c;随便一个研究者都拉起来跑一遍…...

Phi-4-mini-reasoning Chainlit协作功能:多人审阅、批注与推理结果共享

Phi-4-mini-reasoning Chainlit协作功能&#xff1a;多人审阅、批注与推理结果共享 1. 模型概述 Phi-4-mini-reasoning是一个基于合成数据构建的轻量级开源模型&#xff0c;专注于高质量、密集推理的数据处理能力。作为Phi-4模型家族的一员&#xff0c;它经过专门微调以提升数…...

如何用滑模控制(SMC)解决机器人轨迹跟踪中的抖动问题?5个实战技巧分享

如何用滑模控制&#xff08;SMC&#xff09;解决机器人轨迹跟踪中的抖动问题&#xff1f;5个实战技巧分享 当机械臂在执行高精度焊接任务时&#xff0c;末端执行器突然出现5Hz的高频震颤——这种场景对工业机器人工程师而言绝不陌生。滑模控制&#xff08;SMC&#xff09;因其强…...