MySQL 中查询 VARCHAR 类型 JSON 数据的
在数据库设计中,有时我们会将 JSON 数据存储在 VARCHAR 或 TEXT 类型字段中。这种方式虽然灵活,但在查询时需要特别注意。本文将详细介绍如何在 MySQL 中有效查询存储为 VARCHAR 类型的 JSON 数据。
一、问题背景
当 JSON 数据存储在 VARCHAR 列中时,常见的数据格式如下:
[{"id":"1905555466980773889","hasPermission":true},{"id":"1905547884060835841","hasPermission":false}
]
我们需要查询这个 JSON 数组中是否包含特定 ID 的对象。
二、MySQL JSON 函数
MySQL 5.7+ 版本提供了丰富的 JSON 处理函数,即使数据类型是 VARCHAR,只要内容是有效的 JSON,我们仍然可以使用这些函数:
2.1 常用 JSON 函数
JSON_CONTAINS(target, candidate[, path]): 检查 JSON 文档是否包含特定值JSON_EXTRACT(json_doc, path): 从 JSON 文档中提取值JSON_OBJECT(key, val[, key, val]...): 创建 JSON 对象JSON_ARRAY(val[, val]...): 创建 JSON 数组JSON_VALID(json_doc): 验证字符串是否为有效的 JSON
三、查询示例
3.1 基本查询
查询 JSON 数组中包含特定 ID 的记录:
SELECT * FROM sys_user
WHERE app_ids IS NOT NULLAND app_ids != ''AND JSON_CONTAINS(app_ids, JSON_OBJECT('id', '1905555466980773889'));
3.2 查询多个 ID
SELECT * FROM sys_user
WHERE app_ids IS NOT NULLAND app_ids != ''AND (JSON_CONTAINS(app_ids, JSON_OBJECT('id', '1905555466980773889'))OR JSON_CONTAINS(app_ids, JSON_OBJECT('id', '1905547884060835841')));
3.3 使用 JSON_OVERLAPS (MySQL 8.0+)
SELECT * FROM sys_user
WHERE app_ids IS NOT NULLAND app_ids != ''AND JSON_OVERLAPS(app_ids, JSON_ARRAY(JSON_OBJECT('id', '1905555466980773889'),JSON_OBJECT('id', '1905547884060835841')));
3.4 查询特定权限的记录
SELECT * FROM sys_user
WHERE app_ids IS NOT NULLAND app_ids != ''AND JSON_CONTAINS(app_ids, JSON_OBJECT('id', '1905555466980773889', 'hasPermission', true));
四、避免常见错误
4.1 空值处理
JSON_CONTAINS 函数在处理 NULL 或空字符串时会报错,所以需要先排除这些情况:
-- 错误做法
SELECT * FROM sys_user WHERE JSON_CONTAINS(app_ids, JSON_OBJECT('id', '123'));-- 正确做法
SELECT * FROM sys_user
WHERE app_ids IS NOT NULL AND app_ids != '' AND JSON_CONTAINS(app_ids, JSON_OBJECT('id', '123'));
4.2 JSON 格式匹配
确保 JSON_CONTAINS 的第二个参数结构与目标 JSON 中的结构匹配:
-- 错误做法 (直接传入 ID 字符串)
SELECT * FROM sys_user WHERE JSON_CONTAINS(app_ids, '"1905555466980773889"');-- 正确做法 (创建与数组元素匹配的对象)
SELECT * FROM sys_user WHERE JSON_CONTAINS(app_ids, JSON_OBJECT('id', '1905555466980773889'));
4.3 确保 JSON 有效性
添加 JSON_VALID 检查确保字段内容是有效的 JSON:
SELECT * FROM sys_user
WHERE app_ids IS NOT NULLAND app_ids != ''AND JSON_VALID(app_ids) = 1AND JSON_CONTAINS(app_ids, JSON_OBJECT('id', '1905555466980773889'));
五、在 MyBatis Plus 中的应用
5.1 基本查询
LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.isNotNull(SysUser::getAppIds).ne(SysUser::getAppIds, "").apply("JSON_CONTAINS(app_ids, JSON_OBJECT('id', {0}))", "1905555466980773889");List<SysUser> userList = sysUserMapper.selectList(queryWrapper);
5.2 多条件查询
QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
queryWrapper.isNotNull("app_ids").ne("app_ids", "").apply("JSON_VALID(app_ids) = 1").apply("JSON_CONTAINS(app_ids, JSON_OBJECT('id', {0}))", "1905555466980773889");// 如果还要根据权限过滤
queryWrapper.apply("JSON_CONTAINS(app_ids, JSON_OBJECT('id', {0}, 'hasPermission', {1}))", "1905555466980773889", true);
5.3 查询多个 ID
LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.isNotNull(SysUser::getAppIds).ne(SysUser::getAppIds, "").and(w -> w.apply("JSON_CONTAINS(app_ids, JSON_OBJECT('id', {0}))", "1905555466980773889").or().apply("JSON_CONTAINS(app_ids, JSON_OBJECT('id', {0}))", "1905547884060835841"));List<SysUser> userList = sysUserMapper.selectList(queryWrapper);
六、性能优化建议
-
考虑使用 JSON 类型:如果您的 MySQL 版本是 5.7+,考虑使用原生 JSON 类型代替 VARCHAR,这样可以获得更好的性能和功能支持。
-
添加索引:虽然无法直接为 JSON 内容创建索引,但可以使用生成的列和函数索引:
ALTER TABLE sys_user ADD COLUMN app_id_extracted JSON GENERATED ALWAYS AS (JSON_EXTRACT(app_ids, '$[*].id')) VIRTUAL;ALTER TABLE sys_user ADD INDEX idx_app_id_extracted (app_id_extracted); -
定期维护:对于大表,定期 OPTIMIZE TABLE 有助于维护性能。
七、总结
在 MySQL 中查询 VARCHAR 类型的 JSON 数据时,关键是:
- 使用 JSON_CONTAINS 函数并构造正确的 JSON 结构进行匹配
- 处理好 NULL 和空字符串
- 验证 JSON 有效性
- 在 MyBatis Plus 中使用 apply 方法添加原生 SQL 条件
正确使用这些技术可以有效地查询和处理 VARCHAR 中存储的 JSON 数据。
相关文章:
MySQL 中查询 VARCHAR 类型 JSON 数据的
在数据库设计中,有时我们会将 JSON 数据存储在 VARCHAR 或 TEXT 类型字段中。这种方式虽然灵活,但在查询时需要特别注意。本文将详细介绍如何在 MySQL 中有效查询存储为 VARCHAR 类型的 JSON 数据。 一、问题背景 当 JSON 数据存储在 VARCHAR 列中时&a…...
vue2 el-element中el-select选中值,数据已经改变但选择框中不显示值,需要其他输入框输入值才显示这个选择框才会显示刚才选中的值。
项目场景: <el-table-column label"税率" prop"TaxRate" width"180" align"center" show-overflow-tooltip><template slot-scope"{row, $index}"><el-form-item :prop"InquiryItemList. …...
OFDM CP 对解码影响
OFDM符号间会存在ISI,为了解决该问题在符号间插入了循环前缀,可以说这个发明是OFDM能够实用的关键,在多径信道中CP可以有效的解决符号间干扰。3GPP中对于不同SCS 定义了不同的CP长度: 5G Cyclic Prefix (CP) Design -5G Physical …...
oracle em修复之路
很早以前写的文章,再草稿中存放太久了,今天开始整理20年来工作体会,以后陆续发出,希望给大家提供小小的帮助。 去年做的项目使用的oracle数据库,最近要看一下,启动机器进入系统,出现无法加载数…...
STM32学习之ARM内核自带的中断
📢:如果你也对机器人、人工智能感兴趣,看来我们志同道合✨ 📢:不妨浏览一下我的博客主页【https://blog.csdn.net/weixin_51244852】 📢:文章若有幸对你有帮助,可点赞 👍…...
【Windows】Win2008服务器SQL服务监控重启脚本
以下是一个用于监控并自动重启 SQL Server 服务的批处理脚本,适用于 Windows Server 2008 和 SQL Server 2012(默认实例): echo off setlocal enabledelayedexpansion:: 配置参数 set SERVICE_NAMEMSSQLSERVER set LOG_FILEC:\SQ…...
大型语言模型中的工具调用(Function Calling)技术详解
一、引言 随着大型语言模型(LLM)能力的飞速发展,它们在自然语言理解、文本生成、对话交互等方面展现出了令人惊叹的表现。然而,LLM 本身并不具备执行外部操作的能力,比如访问网页、调用第三方 API、执行精确数学运算等…...
Vue3.5 企业级管理系统实战(十四):动态主题切换
动态主题切换是针对用户体验的常见的功能之一,我们可以自己实现如暗黑模式、明亮模式的切换,也可以利用 Element Plus 默认支持的强大动态主题方案实现。这里我们探讨的是后者通过 CSS 变量设置的方案。 1 组件准备 1.1 修改 Navbar 组件 在 src/layo…...
解决Ubuntu20.04安装ROS2的问题(操作记录)
一、ROS 系统安装版本选择 每版的Ubuntu系统版本都有与之对应ROS版本,每一版ROS都有其对应版本的Ubuntu版本,切记不可随便装。ROS 和Ubuntu之间的版本对应关系如下:( 可以从这个网站查看ROS2的各个发行版本的介绍信息。ÿ…...
C# 设置Excel中文本的对齐方式、换行、和旋转
在 Excel 中,对齐、换行和旋转是用于设置单元格内容显示方式的功能。合理的设置这些文本选项可以帮助用户更好地组织和展示 Excel 表格中的数据,使表格更加清晰、易读,提高数据的可视化效果。本文将介绍如何在.NET 程序中通过C# 设置Excel单元…...
Python 的 re.split()
文章目录 栗子:关键点:进阶用法:对比普通 split():典型应用场景: 如何使用 Python 的 re.split() 方法通过正则表达式分割字符串。 栗子: import re s "apple123banana456orange" print(re.sp…...
大数据(6)【Kettle入门指南】从零开始掌握ETL工具:基础操作与实战案例解析
目录 为什么需要Kettle?一、Kettle基础概念与核心功能1.1 什么是Kettle?1.2 核心组件1.3 优势亮点 二、Kettle安装与快速上手2.1 环境准备2.2 启动Spoon 三、实战案例:从CSV到MySQL的数据迁移与清洗3.1 创建转…...
5.DJI-PSDK:Psdk开发负载与Msdk的应用app进行交互:
DJI-PSDK:Psdk开发负载与Msdk的应用app进行交互: 负载设备和无人机使用数据传输模块,在控制命令传输通道上以透传的方式在PSDK和MSDK间传输控制指令。在高速数据传输通道上以透传的方式在PSDK和MSDK间传输数据信息以及用户自定义的数据。使用数据传输功能,不仅可以设置不同…...
RPA VS AI Agent
图片来源网络 RPA(机器人流程自动化)和AI Agent(人工智能代理)在自动化和智能化领域各自扮演着重要角色,但它们之间存在显著的区别。以下是对两者区别的详细分析: 一、定义与核心功能 RPA(机…...
第三节:React 基础篇-React组件通信方案
React 组件通信方案详解及使用场景 以下是 React 组件通信的常用方法及其适用场景,以层级结构呈现: 一、父子组件通信 1. Props 传递 • 实现方式: • 父组件通过 props 向子组件传递数据。 • 子组件通过回调函数 (onEvent) 通知父组件更…...
uniapp大文件分包
1. 在pages.json中配置 "subPackages":[{"root":pagesUser,"pages":[{"path":mine/xxx,"style":xxx },{"path":mine/xxx,"style":xxx}]},{"root":pagesIndex,"pages":[{"p…...
Spark-core编程
sortByKey 函数说明 join 函数说明 leftOuterJoin 函数说明 cogroup 函数说明 RDD行动算子: 行动算子就是会触发action的算子,触发action的含义就是真正的计算数据。 reduce 函数说明 collect 函数说明 foreach 函数说明 count 函数说明 first …...
2025年的Android NDK 快速开发入门
十年前写过一篇介绍NDK开发的文章《Android实战技巧之二十三:Android Studio的NDK开发》,今天看来已经发生了很多变化,NDK开发变得更加容易了。下面就写一篇当下NDK开发快速入门。 **原生开发套件 (NDK) **是一套工具,使开发者能…...
基于springboot的“嗨玩旅游网站”的设计与实现(源码+数据库+文档+PPT)
基于springboot的“嗨玩旅游网站”的设计与实现(源码数据库文档PPT) 开发语言:Java 数据库:MySQL 技术:springboot 工具:IDEA/Ecilpse、Navicat、Maven 系统展示 系统功能结构图 局部E-R图 系统首页界面 系统注册…...
React 之 Redux 第三十一节 useDispatch() 和 useSelector()使用以及详细案例
使用 Redux 实现购物车案例 由于 redux 5.0 已经将 createStore 废弃,我们需要先将 reduxjs/toolkit 安装一下; yarn add reduxjs/toolkit// 或者 npm install reduxjs/toolkit使用 vite 创建 React 项目时候 配置路径别名 : // 第一种写法…...
6.1es新特性解构赋值
解构赋值是 ES6(ECMAScript 2015)引入的语法,通过模式匹配从数组或对象中提取值并赋值给变量。: 功能实现 数组解构:按位置匹配值,如 let [a, b] [1, 2]。对象解构:按属性名匹配值,…...
4月12日随笔
今天大风天气的第一天,周六,早上九点半起来听了排球技术台培训。结果一天都没顾得上看教学视频。黄老师说有排球基础的可以试试当主裁,那一定要争取一下! 上午看了两集小排球,然后开始了解一些中介相关信息。因为下午…...
MCP遇见Web3:从边缘计算到去中心化的无限想象
MCP遇见Web3:从边缘计算到去中心化的无限想象 在数字化转型的浪潮中,边缘计算(MCP,Micro Control Protocol)和Web3技术分别在计算效率与去中心化架构上发挥着各自的优势。当两者融合,会碰撞出哪些火花?作为一名技术极客,我最近开始深度研究MCP与Web3工具的集成,试图探…...
Llama 4全面评测:官方数据亮眼,社区测试显不足之处
引言 2025年4月,Meta正式发布了全新的Llama 4系列模型,这标志着Llama生态系统进入了一个全新的时代。Llama 4不仅是Meta首个原生多模态模型,还采用了混合专家(MoE)架构,并提供了前所未有的上下文长度支持。本文将详细介绍Llama 4…...
【C++】函数直接返回bool值和返回bool变量差异
函数直接返回bool值和返回bool变量差异 背景 在工作中遇到一个比较诡异的问题,场景是给业务方提供的SDK有一个获取状态的函数GetStatus,函数的返回值类型是bool,在测试过程中发现,SDK返回的是false,但是业务方拿到的…...
游戏盾IP可以被破解吗
游戏盾IP(如上海云盾SDK、腾讯云游戏盾)是专为游戏行业设计的高防服务,旨在抵御DDoS攻击、CC攻击等威胁。其安全性取决于技术架构、防护能力以及运维策略。虽然理论上没有绝对“无法破解”的系统,但游戏盾IP在合理…...
第1节:计算机视觉发展简史
计算机视觉与图像分类概述:计算机视觉发展简史 计算机视觉(Computer Vision)作为人工智能领域的重要分支,是一门研究如何使机器"看"的科学,更具体地说,是指用摄影机和计算机代替人眼对目标进行识…...
ARM内核与寄存器
ARM内核与寄存器详解 目录 ARM架构概述ARM处理器模式 Cortex-M3内核的处理器模式Cortex-A系列处理器模式 ARM寄存器集 通用寄存器程序计数器(PC)链接寄存器(LR)堆栈指针(SP)状态寄存器(CPSR/SPSR) 协处理器寄存器NEON和VFP寄存器寄存器使用规范常见ARM指令与寄存器操作 ARM架…...
Hibernate:让对象与数据库无缝对话的全自动ORM框架
一、为什么需要全自动ORM? 在手动编写SQL的时代,开发者需要在Java代码和数据库表之间来回切换: // Java对象 public class User {private Long id;private String name;// getters and setters }// SQL语句 SELECT * FROM user WHERE id ?…...
TDengine 语言连接器(C/C++)
简介 C/C 开发人员可以使用 TDengine 的客户端驱动,即 C/C 连接器(以下都用 TDengine 客户端驱动表示),开发自己的应用来连接 TDengine 集群完成数据存储、查询以及其他功能。TDengine 客户端驱动的 API 类似于 MySQL 的 C API。…...
