MySQL 中查询 VARCHAR 类型 JSON 数据的问题记录

2025-04-14 16:50

本文主要是介绍MySQL 中查询 VARCHAR 类型 JSON 数据的问题记录,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

《MySQL中查询VARCHAR类型JSON数据的问题记录》在数据库设计中,有时我们会将JSON数据存储在VARCHAR或TEXT类型字段中,本文将详细介绍如何在MySQL中有效查询存储为V...

数据库设计中,有时我们会将 JSON 数据存储在 VARCHAR 或 TEXT 类型字段中。这种方式虽然灵活,但在查询时需要特别注意。本文将详细介绍如何http://www.chinasem.cn在 MySQL 中有效查询存储为 VARCHAR 类型的 JSON 数据。

一、问题背景

当 JSON 数据存储在 VARCHAR 列中时,常见的数据格式如下:

[
  {"id":"1905555466980773889","hASPermission":true},
  {"id":"1905547884060835841","hasPermission":false}
]

我们需要查询这个 JSON 数组中是否包含特定 ID javascript的对象。

二、MySQL JSON 函数

MySQL 5.7+ 版本提供了丰富的 JSON 处理函数,即使数据类型是 VARCHAR,只要内容是有效的 JSON,我们仍然可以使用这些函数:

2.1 常用 JSON 函China编程

  • 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 NULL
  AND app_ids != ''
  AND JSON_CONTAINS(app_ids, JSON_OBJECT('id', '1905555466980773889'));

3.2 查询多个 ID

SELECT * FROM sys_user
WHERE 
  app_idsandroid IS NOT NULL
  AND 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 NULL
  AND 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 NULL
  AND 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 NULL
  AND app_ids != ''
  AND JSON_VALID(app_ids) = 1
  AND JSON_CONTAINS(app_ids, JSON_OBJECT('id', '19055554669javascript80773889'));

五、在 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 数据的的文章就介绍到这了,更多相关mysql 查询 VARCHAR 类型 JSON 数据内容请搜索China编程(www.chinasem.cn)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程China编程(www.chinasem.cn)!

这篇关于MySQL 中查询 VARCHAR 类型 JSON 数据的问题记录的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1154211

相关文章

Linux下MySQL数据库定时备份脚本与Crontab配置教学

《Linux下MySQL数据库定时备份脚本与Crontab配置教学》在生产环境中,数据库是核心资产之一,定期备份数据库可以有效防止意外数据丢失,本文将分享一份MySQL定时备份脚本,并讲解如何通过cr... 目录备份脚本详解脚本功能说明授权与可执行权限使用 Crontab 定时执行编辑 Crontab添加定

Vue3绑定props默认值问题

《Vue3绑定props默认值问题》使用Vue3的defineProps配合TypeScript的interface定义props类型,并通过withDefaults设置默认值,使组件能安全访问传入的... 目录前言步骤步骤1:使用 defineProps 定义 Props步骤2:设置默认值总结前言使用T

MyBatis-plus处理存储json数据过程

《MyBatis-plus处理存储json数据过程》文章介绍MyBatis-Plus3.4.21处理对象与集合的差异:对象可用内置Handler配合autoResultMap,集合需自定义处理器继承F... 目录1、如果是对象2、如果需要转换的是List集合总结对象和集合分两种情况处理,目前我用的MP的版本

C#下Newtonsoft.Json的具体使用

《C#下Newtonsoft.Json的具体使用》Newtonsoft.Json是一个非常流行的C#JSON序列化和反序列化库,它可以方便地将C#对象转换为JSON格式,或者将JSON数据解析为C#对... 目录安装 Newtonsoft.json基本用法1. 序列化 C# 对象为 JSON2. 反序列化

MySQL中On duplicate key update的实现示例

《MySQL中Onduplicatekeyupdate的实现示例》ONDUPLICATEKEYUPDATE是一种MySQL的语法,它在插入新数据时,如果遇到唯一键冲突,则会执行更新操作,而不是抛... 目录1/ ON DUPLICATE KEY UPDATE的简介2/ ON DUPLICATE KEY UP

Python中Json和其他类型相互转换的实现示例

《Python中Json和其他类型相互转换的实现示例》本文介绍了在Python中使用json模块实现json数据与dict、object之间的高效转换,包括loads(),load(),dumps()... 项目中经常会用到json格式转为object对象、dict字典格式等。在此做个记录,方便后续用到该方

MySQL分库分表的实践示例

《MySQL分库分表的实践示例》MySQL分库分表适用于数据量大或并发压力高的场景,核心技术包括水平/垂直分片和分库,需应对分布式事务、跨库查询等挑战,通过中间件和解决方案实现,最佳实践为合理策略、备... 目录一、分库分表的触发条件1.1 数据量阈值1.2 并发压力二、分库分表的核心技术模块2.1 水平分

GSON框架下将百度天气JSON数据转JavaBean

《GSON框架下将百度天气JSON数据转JavaBean》这篇文章主要为大家详细介绍了如何在GSON框架下实现将百度天气JSON数据转JavaBean,文中的示例代码讲解详细,感兴趣的小伙伴可以了解下... 目录前言一、百度天气jsON1、请求参数2、返回参数3、属性映射二、GSON属性映射实战1、类对象映

Python与MySQL实现数据库实时同步的详细步骤

《Python与MySQL实现数据库实时同步的详细步骤》在日常开发中,数据同步是一项常见的需求,本篇文章将使用Python和MySQL来实现数据库实时同步,我们将围绕数据变更捕获、数据处理和数据写入这... 目录前言摘要概述:数据同步方案1. 基本思路2. mysql Binlog 简介实现步骤与代码示例1

Web服务器-Nginx-高并发问题

《Web服务器-Nginx-高并发问题》Nginx通过事件驱动、I/O多路复用和异步非阻塞技术高效处理高并发,结合动静分离和限流策略,提升性能与稳定性... 目录前言一、架构1. 原生多进程架构2. 事件驱动模型3. IO多路复用4. 异步非阻塞 I/O5. Nginx高并发配置实战二、动静分离1. 职责2