当前位置: 代码网 > it编程>编程语言>Javascript > MySQL 中查询 VARCHAR 类型 JSON 数据的问题记录

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

2025年04月14日 Javascript 我要评论
在数据库设计中,有时我们会将 json 数据存储在 varchar 或 text 类型字段中。这种方式虽然灵活,但在查询时需要特别注意。本文将详细介绍如何在 mysql 中有效查询存储为 varcha

在数据库设计中,有时我们会将 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 null
  and app_ids != ''
  and json_contains(app_ids, json_object('id', '1905555466980773889'));

3.2 查询多个 id

select * from sys_user
where 
  app_ids 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', '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 数据的的文章就介绍到这了,更多相关mysql 查询 varchar 类型 json 数据内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com