java 中 List<T> 类型数据在 postgreSql 数据库中存储
一 属性添加注解
- 在类上面添加注解:
@TableName(autoResultMap = true)
- 在字段上面添加注解:
@TableField(value = "list", typeHandler = UserHandler.class) private List<User> list = new ArrayList<>();
二 创建 UserHandler 类
package com.demo.handler;import com.baomidou.mybatisplus.extension.handlers.AbstractJsonTypeHandler;
import com.demo.domain.pojo.User;
import org.apache.ibatis.type.MappedTypes;import java.util.List;@MappedTypes({List.class, User.class})
public class UserHandler extends AbstractJsonTypeHandler<List<User>> {@Overrideprotected List<User> parse(String json) {return JsonUtils.fromString(json, List.class, User.class);}@Overrideprotected String toJson(List<User> obj) {return JsonUtils.objectToString(obj);}
}
如果在使用改类时,只需将文件中的 User 替换为自己的类就行
概括下,这个解析器中的 parse 方法类似咱们的 set 方法,是将数据库中的 json 类型数据转为 List 类型数据;反之,toJson 是将 List 类型数据转为 json 数据格式,最后通过 mybatisplus 存储到数据库中. 具体实现可以看下面的 JsonUtils 工具类.
package com.demo.handler;import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import org.apache.commons.lang3.StringUtils;import java.io.IOException;public class JsonUtils {private static final ObjectMapper objectMapper = new ObjectMapper();//初始化相关的配置static {//只引用不为空的值objectMapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);//取消默认转换timestempobjectMapper.configure(SerializationFeature.WRITE_DURATIONS_AS_TIMESTAMPS, false);//忽略空bean转换错误objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);//忽略在json中存在,在java对象不存在的错误objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);// 解决jackson2无法反序列化LocalDateTime的问题objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);objectMapper.registerModule(new JavaTimeModule());}/*** 将java对象转换成json字符串** @param obj java 对象* @param <T>* @return*/public static <T> String objectToString(T obj) {if (obj == null) {return null;}try {return obj instanceof String ? (String) obj : objectMapper.writeValueAsString(obj);} catch (JsonProcessingException e) {e.printStackTrace();return null;}}/*** 将json字符串转换成java对象** @param json 字符串* @param tClass 要转换的对象* @param <T>* @return*/public static <T> T getObjetFormString(String json, Class<T> tClass) {if (StringUtils.isBlank(json) || tClass == null) {return null;}try {return tClass.equals(String.class) ? (T) json : objectMapper.readValue(json, tClass);} catch (IOException e) {e.printStackTrace();return null;}}/*** 将字符串转换成java对象** @param json 字符串* @param tTypeReference 对象* @param <T>* @return*/public static <T> T fromString(String json, TypeReference<T> tTypeReference) {if (StringUtils.isBlank(json) || tTypeReference == null) {return null;}try {return tTypeReference.getType().equals(String.class) ? (T) json : objectMapper.readValue(json, tTypeReference);} catch (IOException e) {e.printStackTrace();return null;}}/*** 将json字符串转换成java集合对象** @param json 字符串* @param collectionClass 集合类型* @param elementClazzes 成员类型* @param <T>* @return*/public static <T> T fromString(String json, Class<?> collectionClass, Class<?>... elementClazzes) {JavaType javaType = objectMapper.getTypeFactory().constructParametricType(collectionClass, elementClazzes);try {return objectMapper.readValue(json, javaType);} catch (IOException e) {e.printStackTrace();return null;}}
}
该文件是工具类,配合 UserHandler 类,无需任何改动,直接粘贴即可
三 数据库字段设置
这里只需要将对应的字段类型设置为 json 即可,这里就不贴图了.
还需要将数据库连接后面加上stringtype=unspecified,例如:
jdbc:postgresql://*.*.*.*:5432/demo?currentSchema=demo,SYS_CATALOG&stringtype=unspecified
否则报错:PSQLException: ERROR: column “list” is of type json but expression is of type varchar
额外说明一个事情,可以说是一个 bug,上述效果在 selectById 查询时是成功的,但是在查询返回体是 List 时,list 字段会返回空集合,问了下 ai,说是数据库为了简洁高效,会跳过解析器,断点测试也确实是这样,至于如何解决,我现在是循环单个查询,最后合并,实属无奈,如果有哪位兄弟能搞定,还麻烦大致说下原因.
文章仓促就之,是在已经已经实现的代码上直接说明,如有读者发现文章有不足或是无法实现效果,可以留言.
如果文章确实有效,还望读者点赞收藏,感谢~
相关文章:
java 中 List<T> 类型数据在 postgreSql 数据库中存储
一 属性添加注解 在类上面添加注解: TableName(autoResultMap true) 在字段上面添加注解: TableField(value "list", typeHandler UserHandler.class) private List<User> list new ArrayList<>(); 二 创建 UserHandler 类…...
公共命名空间,2024年10月的笔记
首先,我国选择C做为竞赛语言,许多人学C,学习的结果是:看到“公共命名空间”,就幻想出一个私有命名空间,其实,公共命名空间和C的命名空间无关! 超简源代码 已知序列v{1,2,3,4,5}&…...
frida脚本,自动化寻址JNI方法
版权归作者所有,如有转发,请注明文章出处:https://cyrus-studio.github.io/blog/ 1. 通过 ArtMethod 结构体找到 jni 方法在内存中的地址,并把寻址方法通过 rpc.exports 暴露给 Python 脚本调用 jni_addr.js let entry_point_fr…...
MySQL中between and的基本用法
文章目录 一、between and语法二、使用示例2.1、between and数值查询2.2、between and时间范围查询2.3、not between and示例 BETWEEN AND操作符可以用于数值、日期等类型的字段,包括边界值。 一、between and语法 MySQL中的BETWEEN AND操作符用于在两个值之间选择…...
Ceph 存储系统全解
1. 引言 什么是 Ceph? Ceph 是一个开源的分布式存储系统,旨在提供高性能、可扩展、无单点故障的统一存储平台。它可以同时支持对象存储、块存储和文件系统存储,能够满足不同存储需求的多种应用场景。Ceph 通过其强大的 RADOS(可…...
C# ftp帮助类 项目实战优化版
上位机开发中有时要与客户的文件服务器进行数据交互。如Mapping文件下载。结果文件上传等。我在项目中就常用到。现在把项目实战代码进行分享一下。 功能列表:连接服务器,下载文件,上传文件,删除服务器文件,获取当前目…...
栈和队列相关|有效的括号|用队列实现栈|用栈实现队列|设计循环队列(C)
20. 有效的括号 判断左右括号是否匹配,匹配返回true,不匹配返回false 通过栈来实现,类型和顺序,数量都要匹配 控制数量通过size 每个右括号都要找最近的左括号去判断类型匹配不匹配,顺序匹配不匹配 最后来判断数量匹配…...
云原生后端开发教程
云原生后端开发教程 引言 随着云计算的普及,云原生架构逐渐成为现代软件开发的主流。云原生不仅仅是将应用部署到云上,而是一种构建和运行应用的方式,充分利用云计算的弹性和灵活性。本文将深入探讨云原生后端开发的核心概念、工具和实践&a…...
TortoiseSVN小乌龟下载安装(Windows11)
目录 TortoiseSVN 1.14.7工具下载安装 TortoiseSVN 1.14.7 工具 系统:Windows 11 下载 官网:https://tortoisesvn.subversion.org.cn/downloads.html如图选 TortoiseSVN 1.14.7 - 64 位 下载完成 安装 打开 next,next Browse…...
Android adb命令获取设备id
Android adb命令获取设备id 方式很多,以下均可获得Android device id: adb shell settings get secure android_id adb shell settings get secure android_id adb devices -l adb shell content query --uri content://settings/secure --where "…...
Skywalking教程一
Skywalking教程一 概述Skywalking功能特点: 概述 一个大型分布式系统架构,监控平台是必不可少的,常用的分布式系统监控平台有:SkyWalking和Prometheus。Skywalking是一款比较优秀的分布式系统监控平台,一款分布式系统…...
React中管理state的方式
使用useState 使用useReducer 既然已经有了useState,为什么还需要useReducer呢? 那么useReducer是如何将解决这些问题的呢? reducer是如何更新state的呢? reducer的工作方式非常类似JavaScript中的reduce方法,随着时…...
服务器数据恢复—RAID5阵列中部分成员盘重组RAID5阵列后如何恢复原raid5阵列数据?
服务器数据恢复环境: 一台服务器挂接一台存储,该存储中有一组由5块硬盘组建的RAID5阵列。 服务器故障: 存储raid5阵列中有一块硬盘掉线。由于RAID5的特性,阵列并没有出现问题。工作一段时间后,服务器出现故障ÿ…...
【Linux】文件切割排序 cut sort
文章目录 Linux文件切割命令:cut1. cut命令的基本用法2. cut命令的选项和参数3. cut命令的实际应用案例 Linux文件排序命令:sort1. sort命令的基本用法2. sort命令的选项和参数3. sort命令的实际应用案例 常见问题和解决方案1. cut和sort命令的联合使用2…...
零售EDI:HornBach EDI 项目案例
HornBach 是一家总部位于德国的家居和建筑材料零售商,成立于1968年。它以大型仓储式商店而闻名,提供广泛的产品,包括建筑材料、园艺、家居装饰和工具等。 近期我们帮助HornBach的供应商W公司成功实现了与HornBach的EDI直连,除了满…...
SpringBoot 集成RabbitMQ 实现钉钉日报定时发送功能
文章目录 一、RabbitMq 下载安装二、开发步骤:1.MAVEN 配置2. RabbitMqConfig 配置3. RabbitMqUtil 工具类4. DailyDelaySendConsumer 消费者监听5. 测试延迟发送 一、RabbitMq 下载安装 官网:https://www.rabbitmq.com/docs 二、开发步骤:…...
基于java ssm springboot女士电商平台系统源码+文档设计
基于java ssm springboot女士电商平台系统源码文档设计 🍅 作者主页 网顺技术团队 🍅 欢迎点赞 👍 收藏 ⭐留言 📝 🍅 文末获取源码联系方式 📝 🍅 查看下方微信号获取联系方式 承接各种定制系统…...
Matlab数字信号处理——基于改进小波变换的图像去噪方法(7种去噪算法)
1.基于小波变换的阈值收缩法去噪 该方法利用小波变换分离出信号中的噪声成分,并通过设置合适的阈值对小波系数进行收缩,保留主要信息的同时,去除噪声。 %基于小波变换的阈值收缩法去噪算法 clear clc Iimread(nana.png); X im2double(I); …...
leetcode hot100【LeetCode 70. 爬楼梯】java实现
LeetCode 70. 爬楼梯 题目描述 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢? 注意: 给定 n 是一个正整数。 示例 1: 输入:n 2 输出:2 解释&…...
Java异常2
异常抛出的两种形式: 系统隐式抛出;int n10/0;—隐式抛出一个异常;手动抛出异常:throw new Exception(); import java.util.InputMismatchException; import java.util.Scanner;public class Main {public static void main(Str…...
深入解析UniApp中的package.json:从基础配置到高级技巧
1. 初识UniApp中的package.json 第一次接触UniApp项目时,我盯着package.json文件看了半天,心想这不就是个管理npm包依赖的配置文件吗?直到踩了几个坑才发现,UniApp对这个文件做了特殊扩展,让它成为了项目配置的中枢神经…...
STEP3-VL-10B性能评测:10B参数模型在A100上吞吐量达18.7 token/s实测
STEP3-VL-10B性能评测:10B参数模型在A100上吞吐量达18.7 token/s实测 最近,阶跃星辰开源了一个让我眼前一亮的模型——STEP3-VL-10B。作为一个10B参数级别的多模态视觉语言模型,它的表现确实让人惊喜。我在A100上实测后发现,它的…...
DeEAR语音情感识别入门必看:三维度(唤醒度/自然度/韵律)原理与Gradio界面实操
DeEAR语音情感识别入门必看:三维度(唤醒度/自然度/韵律)原理与Gradio界面实操 1. 为什么需要语音情感识别 想象一下,当你接到客服电话时,对方的声音是机械冰冷的还是热情自然的?这种差异直接影响沟通效果…...
别再用默认规划器了!手把手教你为TurtleBot3在ROS2 Humble上写个自己的导航大脑
别再用默认规划器了!手把手教你为TurtleBot3在ROS2 Humble上写个自己的导航大脑 当TurtleBot3在狭窄走廊里反复撞墙,或者面对动态障碍物时反应迟钝,大多数开发者首先想到的是调整Nav2的默认参数。但真正的高手都知道——与其在有限的黑箱参数…...
在CentOS 7上远程跑3D应用:保姆级TurboVNC+VirtualGL配置与GPU调用验证
在CentOS 7上构建高性能远程3D工作站:TurboVNC与VirtualGL深度配置指南 当工程师需要远程操控配备NVIDIA GPU的服务器运行Maya、Paraview或TensorBoard等图形密集型应用时,直接使用传统VNC会遇到3D渲染性能低下的问题。本方案通过TurboVNC的高效压缩传输…...
拆解二进制炸弹:从GDB调试到浮点数逆向的实战技巧
拆解二进制炸弹:从GDB调试到浮点数逆向的实战技巧 逆向工程就像一场数字世界的考古探险,而二进制炸弹程序则是绝佳的练习场。本文将带你深入Linux环境下使用GDB进行动态调试的完整过程,特别聚焦浮点数表示阶段的逆向技巧。无论你是计算机专业…...
提示工程架构师进阶之路:AI提示设计用户体验的无障碍设计指南
提示工程架构师进阶:AI提示设计的无障碍体验指南——让每一句交互都“触手可及” 摘要:为什么你的AI提示,可能把16%的用户拒之门外? 清晨7点,张阿姨对着手机里的AI助手说:“帮我订张下周三去闺女家的火车票。” 助手回复:“请提供具体的出发地、目的地及日期。” 张阿…...
Intel RealSense深度相机3D点云生成终极指南:从原理到实战
Intel RealSense深度相机3D点云生成终极指南:从原理到实战 【免费下载链接】librealsense Intel RealSense™ SDK 项目地址: https://gitcode.com/GitHub_Trending/li/librealsense 想要快速构建高质量的三维视觉应用?Intel RealSense深度相机为你…...
OpenClaw低配适配:nanobot在4GB内存设备运行技巧
OpenClaw低配适配:nanobot在4GB内存设备运行技巧 1. 为什么要在低配设备上运行OpenClaw? 去年夏天,我在整理一台2015年的老笔记本时突发奇想:这台只有4GB内存的"古董"能否跑得动OpenClaw?当时市面上大多数…...
OpenClaw+GLM-4.7-Flash:智能会议纪要生成系统
OpenClawGLM-4.7-Flash:智能会议纪要生成系统 1. 为什么需要自动化会议纪要 每次开完会最痛苦的事情是什么?对我来说就是整理会议纪要。作为技术负责人,我每周要参加至少5场会议,从需求评审到技术方案讨论,再到项目复…...
