Springboot+PostgreSQL+MybatisPlus存储JSON或List、数组(Array)数据

embedded/2024/12/21 9:21:52/

项目架构

Springboot+PostgreSQL+MybatisPlus
从Mongodb转过来的项目,有存储json数据的需求,但是在mybatis-plus上会出点问题
报错: Error updating database. Cause: org.postgresql.util.PSQLException 字段 “” 的类型为 jsonb, 但表达式的类型为 character varying 建议:你需要重写或转换表达式

实体类定义:

@EqualsAndHashCode(callSuper = true)
@Data
@TableName("tb_user_role")
@FieldDefaults(level = AccessLevel.PRIVATE)
public class TbUserRole extends BaseEntity {@TableField("user_id")String userId;@JsonInclude(JsonInclude.Include.NON_EMPTY)List<String> roles; // 存储为 JSONB@JsonInclude(JsonInclude.Include.NON_EMPTY)List<String> permissions; // 存储为 JSONB
}

SQL

CREATE TABLE tb_user_role (id VARCHAR(255) PRIMARY KEY, -- 主键ID,继承自 BaseEntityuser_id VARCHAR(255) NOT NULL, -- 用户IDroles JSONB, -- 角色,存储为 JSONB 类型permissions JSONB, -- 权限,存储为 JSONB 类型deleted BOOLEAN DEFAULT FALSE, -- 逻辑删除标识create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP, -- 创建时间update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP -- 更新时间
);

前端传入的结构

     @Schema(description = "角色,传入的对象需要从Role接口获取")List<String> roles;@Schema(description = "权限,传入的对象需要从Permission接口获取")List<String> permissions;

存储时的问题

Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@1c1e6475]
2024-09-27 17:48:43.398 ERROR [tid] [sid] [pid] [nio-8050-exec-1] c.s.w.h.GlobalExceptionHandler@viewExceptionHandler:66 : 
### Error updating database.  Cause: org.postgresql.util.PSQLException: 错误: 字段 "roles" 的类型为 jsonb, 但表达式的类型为 character varying建议:你需要重写或转换表达式位置:117
### The error may exist in com/sgcchg/data/mapper/UserRoleMapper.java (best guess)
### The error may involve com.sgcchg.data.mapper.UserRoleMapper.insert-Inline
### The error occurred while setting parameters
### SQL: INSERT INTO tb_user_role  ( id, user_id, roles, permissions, deleted, create_time, update_time )  VALUES (  ?, ?, ?, ?, ?, ?, ?  )
### Cause: org.postgresql.util.PSQLException: 错误: 字段 "roles" 的类型为 jsonb, 但表达式的类型为 character varying建议:你需要重写或转换表达式位置:117
; bad SQL grammar []; nested exception is org.postgresql.util.PSQLException: 错误: 字段 "roles" 的类型为 jsonb, 但表达式的类型为 character varying建议:你需要重写或转换表达式位置:117 location: com.sgcchg.business.impl.user.UserServiceImpl:101

问题解决

修改Entity定义

@EqualsAndHashCode(callSuper = true)
@Data
@TableName("tb_user_role")
@FieldDefaults(level = AccessLevel.PRIVATE)
public class TbUserRole extends BaseEntity {@TableField("user_id")String userId;@TableField(typeHandler = ListToStringTypeHandler.class)@JsonInclude(JsonInclude.Include.NON_EMPTY)List<String> roles; // 存储为 JSONB@TableField(typeHandler = ListToStringTypeHandler.class)@JsonInclude(JsonInclude.Include.NON_EMPTY)List<String> permissions; // 存储为 JSONB
}

添加TypeHandler

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Collections;
import java.util.List;public class ListToStringTypeHandler extends BaseTypeHandler<List<String>> {private static final ObjectMapper objectMapper = new ObjectMapper();//    @Override
//    public void setNonNullParameter(PreparedStatement ps, int i, List<String> parameter, JdbcType jdbcType) throws SQLException {
//        // 将 List 转为 JSON 字符串存储
//        try {
//            ps.setString(i, objectMapper.writeValueAsString(parameter));
//        } catch (JsonProcessingException e) {
//            throw new SQLException("Could not convert list to JSON", e);
//        }
//    }@Overridepublic void setNonNullParameter(PreparedStatement ps, int i, List<String> parameter, JdbcType jdbcType) throws SQLException {try {String jsonString = objectMapper.writeValueAsString(parameter);ps.setObject(i, jsonString, JdbcType.OTHER.TYPE_CODE); // 使用 JDBC 的 OTHER 类型插入 JSONB} catch (JsonProcessingException e) {throw new SQLException("Could not convert list to JSON", e);}}@Overridepublic List<String> getNullableResult(ResultSet rs, String columnName) throws SQLException {String json = rs.getString(columnName);return parseJsonToList(json);}@Overridepublic List<String> getNullableResult(ResultSet rs, int columnIndex) throws SQLException {String json = rs.getString(columnIndex);return parseJsonToList(json);}@Overridepublic List<String> getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {String json = cs.getString(columnIndex);return parseJsonToList(json);}private List<String> parseJsonToList(String json) {if (json == null || json.trim().isEmpty()) {return Collections.emptyList();}try {return objectMapper.readValue(json, List.class);} catch (JsonProcessingException e) {return Collections.emptyList();}}}

保存数据

之后即可保存数据
在数据库中可看到:
在这里插入图片描述


http://www.ppmy.cn/embedded/121760.html

相关文章

Elasticsearch 开放推理 API 增加了对 Google AI Studio 的支持

作者&#xff1a;来自 Elastic Jeff Vestal 我们很高兴地宣布 Elasticsearch 的开放推理 API 支持 Gemini 开发者 API。使用 Google AI Studio 时&#xff0c;开发者现在可以与 Elasticsearch 索引中的数据进行聊天、运行实验并使用 Google Cloud 的模型&#xff08;例如 Gemin…

Prometheus之Pushgateway使用

Pushgateway属于整个架构图的这一部分 The Pushgateway is an intermediary service which allows you to push metrics from jobs which cannot be scraped. The Prometheus Pushgateway exists to allow ephemeral and batch jobs to expose their metrics to Prometheus. S…

Git大框架总结

下面首先是我对于git的一个小总结&#xff0c;主要是大框架 首先是四区&#xff0c;因为大部分你所有的工作都是在这四个区里的实现的&#xff0c;包括要提交一个东西&#xff0c;是先是在工作区修改&#xff0c;后用add添加到暂存区&#xff0c;后提交到本地仓库&#xff0c;当…

C语言基础之数组

上一篇讲述了C语言函数的使用&#xff0c;本文讲述数组的相关概念&#xff0c;通过一维数组、二维数组、数组越界等详细讲解数组相关的具体内容&#xff0c;以辅助读者了解并掌握数组相关概念。 一维数组 一维数组的定义与创建 若无数组&#xff0c;我们要存储一堆类型相同的…

OpenCV-图像透视变换

文章目录 一、定义与原理二、应用场景三、实现方法四、代码运用 图像的透视变换&#xff08;Perspective Transformation&#xff09;是一种在图像处理中广泛使用的技术&#xff0c;它通过模拟人眼或相机镜头观看三维空间物体时的透视效果&#xff0c;来改变图像的视角和形状。…

Camera Raw:打开图像

在图像工作流程中&#xff0c;无论是 Raw 格式图像文件还是 JPEG、TIFF 文件&#xff0c;都可以先使用 Camera Raw 打开并调整后&#xff0c;再进入其它 Adobe 软件如 Photoshop 中进行进一步的编辑和处理。 一、打开 Raw 格式图像 1、通过 Adobe Bridge 打开 在 Adobe Bridge …

基于单片机的小车行走加温湿度检测系统

目录 一、主要功能 二、硬件资源 三、程序编程 四、实现现象 一、主要功能 基于51单片机&#xff0c;采样DHT11温湿度传感器检测温湿度&#xff0c;滑动变阻器连接数码转换器模拟电量采集传感器&#xff0c; 电机采样L298N驱动&#xff0c;各项参数通过LCD1602显示&#x…

kali linux 终端复用和界面移动

kali linux 终端复用和界面移动 经验和操作 渗透测试的工具选择考虑 01 能用命令行就不用图形ui 图形ui 容易对细节隐藏&#xff0c;命令行工具的在终端输出的日志相对透明&#xff0c;容易观察和调整 wireshark – tcpdump burpsuit – curl( web 访问相关), wfuzz(模糊测…