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

mybatis查询修改mysql的json字段

前言:

mysql5.7版本之后支持json字段类型,推荐mysql8版本,适用于属性不确定的个性化字段,比如:
身份信息{“职业”,“学生”,“兴趣”:“打乒乓球”,“特长”:“跳高,书法”};
图片信息{“日期”:“2023-12-12 22:12”,“尺寸”:“215*720”,“拍摄地”:“xxx”,“作者”:“xxx”};
标签信息:[“历史”,“军事”,“都市”,“科幻”]。
这部分信息每条数据差异较大,固定字段会大量冗余,使用json有较高的扩展性和自由度

JSON对象除了支持字符串、整型、日期类型,JSON 内嵌的字段也支持数组类型

sql语句中对json的新增和查询

新增

CREATE TABLE UserLogin (userId BIGINT NOT NULL,loginInfo JSON,PRIMARY KEY(userId)
);
SET @a = '
{"cellphone" : "1","wxchat" : "码农","77" : "1"
}';
INSERT INTO UserLogin VALUES (1,@a);

查询

字段回显
SELECTuserId,JSON_UNQUOTE(JSON_EXTRACT(loginInfo,"$.cellphone")) cellphone,JSON_UNQUOTE(JSON_EXTRACT(loginInfo,"$.wxchat")) wxchat
FROM UserLogin;
等效于SELECT userId,loginInfo->>"$.cellphone" cellphone,loginInfo->>"$.wxchat" wxchat
FROM UserLogin;
条件筛选
CREATE TABLE `photos ` (`id` bigint NOT NULL COMMENT '文件在云端的唯一标识ID',`tags` json DEFAULT NULL COMMENT '标签数组',`info` json DEFAULT NULL COMMENT '照片生成信息json',PRIMARY KEY (`id`) USING BTREE
);-- json字段属性筛选,查询拍摄地是重庆的
SELECT * FROM photos WHERE JSON_EXTRACT(info, '$.拍摄地') = '重庆';-- 查询标签包含10的图片
SELECT * FROM photos WHERE 10 MEMBER OF(tags->"$");-- 查询标签包含2和10的图片
SELECT * FROM photos WHERE JSON_CONTAINS(tags->"$", '[2,10]');
-- 或者
SELECT * FROM photos WHERE JSON_OVERLAPS(tags->"$", '[2,10]');JSON_CONTAINS 返回json数组是否包含指定的数组
JSON_OVERLAPS 返回json数组是否与指定的数组有交集

建立索引

相当于增加虚拟列

-- 为json中的手机号建立索引
ALTER TABLE UserLogin ADD COLUMN cellphone VARCHAR(255) AS (loginInfo->>"$.cellphone");
ALTER TABLE UserLogin ADD UNIQUE INDEX idx_cellphone(cellphone);-- 也可以在建表时创建索引CREATE TABLE UserLogin (userId BIGINT,loginInfo JSON,cellphone VARCHAR(255) AS (loginInfo->>"$.cellphone"),PRIMARY KEY(userId),UNIQUE KEY uk_idx_cellphone(cellphone)
);-- 使用索引的虚拟列查询
SELECT  *  FROM UserLogin WHERE cellphone = '11'

mybatis自定义转换

mysql与java实体常见的字段映射不需要我们特别指定,json字段因为其灵活性,需要单独指定。
我这里列举出上例中photos表的json与java实体的map和list的转换,
如果你的java实体中json字段映射的其他类型直接在示例转换上修改类型即可。
(也可以用泛型写通用转换)

json == > Map<String,Object>

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.TypeHandler;import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Map;public class CustomJsonTypeHandler implements TypeHandler<Map<String, Object>> {private static final ObjectMapper objectMapper = new ObjectMapper();@Overridepublic void setParameter(PreparedStatement ps, int i, Map<String, Object> parameter, JdbcType jdbcType) throws SQLException {try {String json = objectMapper.writeValueAsString(parameter);ps.setString(i, json);} catch (JsonProcessingException e) {throw new SQLException("Error converting Map to JSON");}}@Overridepublic Map<String, Object> getResult(ResultSet rs, String columnName) throws SQLException {String json = rs.getString(columnName);return fromJson(json);}@Overridepublic Map<String, Object> getResult(ResultSet rs, int columnIndex) throws SQLException {String json = rs.getString(columnIndex);return fromJson(json);}@Overridepublic Map<String, Object> getResult(CallableStatement cs, int columnIndex) throws SQLException {String json = cs.getString(columnIndex);return fromJson(json);}private Map<String, Object> fromJson(String json) throws SQLException {if (json == null || json.isEmpty()) {return null;}try {return objectMapper.readValue(json, Map.class);} catch (JsonProcessingException e) {throw new SQLException("Error converting JSON to Map");}}
}

json == > List

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.TypeHandler;import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;public class JsonArrayTypeHandler implements TypeHandler<List<String>> {private static final ObjectMapper objectMapper = new ObjectMapper();@Overridepublic void setParameter(PreparedStatement ps, int i, List<String> parameter, JdbcType jdbcType) throws SQLException {try {String json = objectMapper.writeValueAsString(parameter);ps.setString(i, json);} catch (JsonProcessingException e) {throw new SQLException("Error converting Integer[] to JSON");}}@Overridepublic List<String> getResult(ResultSet rs, String columnName) throws SQLException {String json = rs.getString(columnName);return fromJson(json);}@Overridepublic List<String> getResult(ResultSet rs, int columnIndex) throws SQLException {String json = rs.getString(columnIndex);return fromJson(json);}@Overridepublic List<String> getResult(CallableStatement cs, int columnIndex) throws SQLException {String json = cs.getString(columnIndex);return fromJson(json);}private List<String> fromJson(String json) throws SQLException {if (json == null || json.isEmpty()) {return null;}try {return objectMapper.readValue(json, List.class);} catch (JsonProcessingException e) {throw new SQLException("Error converting JSON to Integer[]");}}
}

mapper.xml中的输入与输出

输入

	-- 新增信息<insert id="insertPhotos" parameterType="Photos">insert into photos<trim prefix="(" suffix=")" suffixOverrides=","><if test="tags != null">tags,</if><if test="info != null">info,</if></trim><trim prefix="values (" suffix=")" suffixOverrides=","><if test="tags != null">#{tags, typeHandler=com.ruoyi.web.core.config.JsonArrayTypeHandler},</if><if test="info != null">#{info,typeHandler=com.ruoyi.web.core.config.CustomJsonTypeHandler},</if></trim></insert>-- 修改信息<update id="updatePhotos" parameterType="Photos">update photos<trim prefix="SET" suffixOverrides=","><if test="info  != null">info = #{info,typeHandler=com.ruoyi.web.core.config.CustomJsonTypeHandler},</if><if test="tags != null">tags = #{tags,typeHandler=com.ruoyi.web.core.config.JsonArrayTypeHandler},</if></trim>where id= #{id}</update>

输出

    <resultMap type="Photos" id="PhotosResult"><result property="id" column="id"/><result property="tags" column="tags" javaType="java.util.List" typeHandler="com.ruoyi.web.core.config.JsonArrayTypeHandler"/><result property="info" column="tags" javaType="java.util.List" typeHandler="com.ruoyi.web.core.config.CustomJsonTypeHandler"/></resultMap><select id="PhotosList" parameterType="Photos" resultMap="PhotosResult"><include refid="selectPhotosVo"/><where><if test="id != null ">and id = #{id}</if><if test="tags != null ">and JSON_CONTAINS(tags->"$",#{tags, typeHandler=com.ruoyi.web.core.config.JsonArrayTypeHandler})</if></where></select>

部分json查询语法参考文章:https://mp.weixin.qq.com/s?src=11&timestamp=1706855643&ver=5055&signature=xH0-aTP0U1liqYAzXaSvvqAqto5UUiPrJY5P1-qizaGNTpmSTV7ZY7qkqyMujiUWM8dhenWhjDLecMoMgeXBwMYffwSSbLKe2UrQ308ZaDBUaVJ4ku29U0X05XZh&new=1

相关文章:

mybatis查询修改mysql的json字段

前言&#xff1a; mysql5.7版本之后支持json字段类型&#xff0c;推荐mysql8版本&#xff0c;适用于属性不确定的个性化字段&#xff0c;比如: 身份信息{“职业”,“学生”,“兴趣”:“打乒乓球”,“特长”:“跳高&#xff0c;书法”}; 图片信息{“日期”:“2023-12-12 22:12”…...

实时聊天系统

这个系统可以用于网站的即时通讯&#xff0c;比如客服系统、在线社区等。这个功能不仅对用户友好&#xff0c;而且也是检验技术实现能力的一个很好的案例。 ### 功能概述 该系统允许用户在网站上实时发送和接收消息。为了保持实时性&#xff0c;我们将使用PHP进行服务器端的逻…...

Spring-mvc、Spring-boot中如何在调用同类方法时触发AOP

1. 问题描述 Spring-mvc和Spring-boot中aop可以实现代理的功能&#xff0c;我们可以借此实现事务和日志记录或者限流等多种操作。但是&#xff0c;如果你在一个方法中调用其同类下的其他方法的时候不会触发AOP。本文主要说明其原因及解决办法和实现原理。 2. 原因 AIOP的本质是…...

幻兽帕鲁服务器自动重启备份-python

幻兽帕鲁服务器自动重启备份-python 1. 前置知识点2. 目录结构3. 代码内容4. 原理解释5. 额外备注 基于python编写的服务器全自动管理工具&#xff0c;能够实现自动定时备份存档&#xff0c;以及在检测到服务器崩溃之后自动重新启动&#xff0c;并且整合了对于frp端口转发工具的…...

C# Onnx yolov8 水表读数检测

目录 效果 模型信息 项目 代码 训练数据 下载 C# Onnx yolov8 水表读数检测 效果 模型信息 Model Properties ------------------------- date&#xff1a;2024-01-31T10:18:10.141465 author&#xff1a;Ultralytics task&#xff1a;detect license&#xff1a;AGPL-…...

负载均衡下webshell连接

目录 一、什么是负载均衡 分类 负载均衡算法 分类介绍 分类 均衡技术 主要应用 安装docker-compose 2.1上传的文件丢失 2.2 命令执行时的漂移 2.3 大工具投放失败 2.4 内网穿透工具失效 3.一些解决方案 总结 一、什么是负载均衡 负载均衡&#xff08;Load Balanc…...

Spring面试大全-基础知识01

1.什么是Spring Spring框架是用于构建企业级Java的开源框架&#xff0c;他通过依赖注入和IOC容器帮我我们管理对象&#xff1b;支持AOP&#xff0c;将非业务功能&#xff08;日志&#xff0c;事务等&#xff09;从我们业务代码中分离出来&#xff0c;提高了代码的可维护性&…...

Transformer实战-系列教程4:Vision Transformer 源码解读2

&#x1f6a9;&#x1f6a9;&#x1f6a9;Transformer实战-系列教程总目录 有任何问题欢迎在下面留言 本篇文章的代码运行界面均在Pycharm中进行 本篇文章配套的代码资源已经上传 4、Embbeding类 self.embeddings Embeddings(config, img_sizeimg_size) class Embeddings(nn.…...

cesium-水平测距

cesium测量两点间的距离 <template><div id"cesiumContainer" style"height: 100vh;"></div><div id"toolbar" style"position: fixed;top:20px;left:220px;"><el-breadcrumb><el-breadcrumb-item&…...

【Android-Compose】手势检测实现按下、单击、双击、长按事件,以及避免频繁单击事件的简单方法

目录&#xff1a; 1 不需要双击事件 规避频繁单击事件2 需要双击事件&#xff08;常规写法&#xff09;3 后记&#xff1a;不建议使用上面的代码自定义按钮 1 不需要双击事件 规避频繁单击事件 var firstClickTime by remember { mutableStateOf(System.currentTimeMillis()…...

AUTOSAR汽车电子嵌入式编程精讲300篇-基于神经网络的CAN总线负载率优化(续)

目录 3.3 SA 算法 3.3.1 SA 算法原理 3.3.2 基于 SA 算法 CAN 总线负载率优化分析...

python爬虫6—高性能异步爬虫

如果有多个URL等待我们爬取&#xff0c;我们通常是一次只能爬取一个&#xff0c;爬取效率低&#xff0c;异步爬虫可以提高爬取效率&#xff0c;可以一次多多个URL同时同时发起请求 异步爬虫方式&#xff1a; 一、多线程、多进程&#xff08;不建议&#xff09;&#xff1a;可以…...

日历功能——C语言

实现日历功能&#xff0c;输入年份月份&#xff0c;输出日历 #include<stdio.h>int leap_year(int year) {if(year % 4 0 && year % 100 ! 0 || year % 400 0){return 1;}else{return 0;} }int determine_year_month_day(int *day,int month,int year) {if(mo…...

GPIO中断

1.EXTI简介 EXTI是External Interrupt的缩写&#xff0c;指外部中断。在嵌入式系统中&#xff0c;外部中断是一种用于处理外部事件的机制。当外部事件发生时&#xff08;比如按下按钮、传感器信号变化等&#xff09;&#xff0c;外部中断可以立即打断正在执行的程序&#xff0…...

springboot完成一个线上图片存放地址+实现前后端上传图片+回显

1.路径 注意路径 2.代码&#xff1a;&#xff08;那个imagePath没什么用&#xff0c;懒的删了&#xff09;&#xff0c;注意你的本地文件夹要有图片&#xff0c;才可以在线上地址中打开查看 package com.xxx.common.config;import org.springframework.beans.factory.annotat…...

编程思维与生活琐事的内在关联及其应用价值

随着科技的日益普及和信息化时代的到来&#xff0c;编程作为一种现代技能&#xff0c;其影响已不再局限于专业领域&#xff0c;而是逐步渗透到人们的日常生活之中。探讨编程与生活琐事之间的关系&#xff0c;有助于我们更好地理解如何将技术智慧应用于日常管理&#xff0c;提升…...

OSPF排错

目录 实验拓扑图 实验要求 实验排错 故障一 故障现象 故障分析 故障解决 故障二 故障现象 故障分析 故障解决 故障三 故障现象 故障分析 故障解决 故障四 故障现象 故障分析 故障解决 故障五 故障现象 故障分析 故障解决 故障六 故障现象 故障分析 …...

day07-CSS高级

01-定位 作用&#xff1a;灵活的改变盒子在网页中的位置 实现&#xff1a; 1.定位模式&#xff1a;position 2.边偏移&#xff1a;设置盒子的位置 left right top bottom 相对定位 position: relative 特点&#xff1a; 不脱标&#xff0c;占用自己原来位置 显示模…...

05 MP之ActiveRecord模式+SimpleQuery

1. ActiveRecord ActiveRecord(活动记录&#xff0c;简称AR)&#xff0c;是一种领域模型模式&#xff0c;特点是一个模型类对应关系型数据库中的一个表&#xff0c;而模型类的一个实例对应表中的一行记录。 其目标是通过围绕一个数据对象, 进行全部的CRUD操作。 1.1 让实体类…...

git diff查看比对两次不同时间点提交的异同

git diff查看比对两次不同时间点提交的异同 用 git diff命令&#xff1a; git diff commit-id-1 commit-id-2 不同commit-id在不同的时间点提交产生&#xff0c;因为也可以认为git diff是比对两个不同时间点的代码异同。 git diff比较不同commit版本的代码文件异同_git diff c…...

JPEGView:Windows平台下的极速图像查看与编辑解决方案

JPEGView&#xff1a;Windows平台下的极速图像查看与编辑解决方案 【免费下载链接】jpegview Fork of JPEGView by David Kleiner - fast and highly configurable viewer/editor for JPEG, BMP, PNG, WEBP, TGA, GIF and TIFF images with a minimal GUI. Basic on-the-fly im…...

Power BI主题模板终极指南:30+免费JSON模板快速美化数据报表

Power BI主题模板终极指南&#xff1a;30免费JSON模板快速美化数据报表 【免费下载链接】PowerBI-ThemeTemplates Snippets for assembling Power BI Themes 项目地址: https://gitcode.com/gh_mirrors/po/PowerBI-ThemeTemplates 想要让Power BI报表瞬间焕发专业魅力吗…...

开源辅助工具YimMenu:GTA5安全使用指南与进阶技巧

开源辅助工具YimMenu&#xff1a;GTA5安全使用指南与进阶技巧 【免费下载链接】YimMenu YimMenu, a GTA V menu protecting against a wide ranges of the public crashes and improving the overall experience. 项目地址: https://gitcode.com/GitHub_Trending/yi/YimMenu …...

从芯片手册到稳定波形:深入解读74LS161的异步清零与同步计数,搞定数字钟六十进制

从芯片手册到稳定波形&#xff1a;深入解读74LS161的异步清零与同步计数&#xff0c;搞定数字钟六十进制 在数字电路设计中&#xff0c;计数器芯片74LS161的应用无处不在&#xff0c;从简单的分频器到复杂的数字钟系统都能见到它的身影。但真正深入理解这颗经典芯片内部工作机…...

如何利用内部链接来提高网站排名_网站 UX 设计对 SEO 的重要性是什么

如何利用内部链接来提高网站排名 在现代的网络环境中&#xff0c;如何提高网站在搜索引擎中的排名成为了每一个网站运萈者的首要任务。其中&#xff0c;内部链接和网站用户体验&#xff08;UX&#xff09;设计在搜索引擎优化&#xff08;SEO&#xff09;中扮演了至关重要的角色…...

Python爬虫入门:10步快速掌握网页数据抓取,【大数据实战】如何从0到1构建用户画像系统(案例+数据仓库+Airflow调度)。

准备工作 安装Python环境&#xff0c;确保版本在3.6以上。推荐使用Anaconda管理Python环境&#xff0c;避免版本冲突。安装必要的库&#xff0c;如requests、BeautifulSoup、lxml等。可以通过pip命令快速安装&#xff1a; pip install requests beautifulsoup4 lxml理解基本概念…...

WarcraftHelper:面向魔兽争霸III玩家的全方位优化解决方案

WarcraftHelper&#xff1a;面向魔兽争霸III玩家的全方位优化解决方案 【免费下载链接】WarcraftHelper Warcraft III Helper , support 1.20e, 1.24e, 1.26a, 1.27a, 1.27b 项目地址: https://gitcode.com/gh_mirrors/wa/WarcraftHelper WarcraftHelper是一款专为魔兽争…...

智能家居中枢:OpenClaw+Qwen3-14B镜像控制HomeAssistant

智能家居中枢&#xff1a;OpenClawQwen3-14B镜像控制HomeAssistant 1. 为什么需要AI驱动的智能家居中枢&#xff1f; 去年装修新房时&#xff0c;我安装了近30个智能设备——从窗帘电机到温湿度传感器&#xff0c;全部接入了HomeAssistant系统。但很快发现一个问题&#xff1…...

3步掌握MTKClient:从零基础到设备调试的完整指南

3步掌握MTKClient&#xff1a;从零基础到设备调试的完整指南 【免费下载链接】mtkclient MTK reverse engineering and flash tool 项目地址: https://gitcode.com/gh_mirrors/mt/mtkclient MTKClient是一款功能强大的联发科芯片调试工具&#xff0c;能够帮助开发者进行…...

【VBA】【EXCEL】工作日_节假日

Option Explicit 函数一&#xff1a;计算两个日期之间的工作日天数用法&#xff1a;CalcWorkDays(开始日期, 结束日期)示例&#xff1a;CalcWorkDays(A1,B1)Function CalcWorkDays(startDate As Date, endDate As Date) As LongDim i As DateDim workCount As LongDim isHolida…...