MySql中json类型数据的查询以及在MyBatis-Plus中的使用

2023-11-14

表结构和初始数据

  • 新建表结构
CREATE TABLE `json_test` (
  `id` int NOT NULL AUTO_INCREMENT,
  `roles` json DEFAULT NULL COMMENT '角色',
  `project` json DEFAULT NULL COMMENT '项目',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB;
复制代码
  • 初始数据
INSERT INTO `ctts_dev`.`json_test`(`id`, `roles`, `project`) VALUES (1, '[{"id": 10001, "name": "管理员"}, {"id": 10002, "name": "开发"}, {"id": 10003, "name": "测试"}]', '{"id": 11111, "name": "项目1"}');
INSERT INTO `ctts_dev`.`json_test`(`id`, `roles`, `project`) VALUES (2, '[{"id": 10002, "name": "开发"}]', '{"id": 22222, "name": "项目2"}');
INSERT INTO `ctts_dev`.`json_test`(`id`, `roles`, `project`) VALUES (3, '[{"id": 10003, "name": "测试"}]', '{"id": 11111, "name": "项目1"}');
复制代码

其中 roles 字段存的是 数组

[{"id":10001,"name":"管理员"},{"id":10002,"name":"开发"},{"id":10003,"name":"测试"}]
复制代码

project 存的是 对象

{"id": 11111, "name": "项目1"}
复制代码

对象JSON查询

查询 project 是 项目1 的(精准查询)

  • 使用箭头函数
SELECT * FROM json_test 
WHERE project -> '$.name' = '项目1'
复制代码
  • 使用 JSON_CONTAINS
SELECT * FROM json_test 
WHERE JSON_CONTAINS(project, JSON_OBJECT('name', '项目1'))
复制代码

模糊查询 project 字段

SELECT * FROM json_test 
WHERE project -> '$.name' like '%项目%'
复制代码

数组JSON查询

查询 roles 中包含 测试 的(精准查询)

SELECT * FROM json_test 
WHERE JSON_CONTAINS(roles,JSON_OBJECT('name','测试'))
复制代码

模糊查询 roles 字段

SELECT * FROM json_test
WHERE roles -> '$[*].name' like '%测%'
复制代码

其中,中括号里的 星号 ,也可以替换为数组中的下标index

SELECT * FROM json_test
WHERE roles -> '$[1].name' like '%测%'
复制代码

这样就是模糊查询在数组中第二个元素是否含有  字的,

提取JSON中数据

提取 json 中单个字段的值

SELECT
    id,
    roles -> '$[*].name' AS roleName,
    project ->> '$.name' AS projectName 
FROM
    json_test
复制代码

也提供了 JSON_EXTRACT 函数,结果和上面是一样的,只是查询出的 projectName 是带双引号的

SELECT
    id,
    JSON_EXTRACT( roles, '$[*].name' ) AS roleName,
    JSON_EXTRACT( project, '$.name' ) AS projectName 
FROM
    json_test
复制代码

如果不需要双引号,可以使用 JSON_UNQUOTE 函数

提取 json 中所有字段的值,用 星号 就行

SELECT
    id,
    roles -> '$[*].*' AS roleName,
    project ->> '$.*' AS projectName 
FROM
    json_test
复制代码

一个箭头和两个箭头的区别

MySql中箭头函数,一个箭头和两个箭头的区别

如果是字符串,一个箭头返回的结果是带双引号的(只针对字符串),两个箭头是不带的

SELECT project -> '$.name' as projectName FROM json_test;
"项目1"
"项目2"
"项目1"

SELECT project ->> '$.name' as projectName FROM json_test;
项目1
项目2
项目1
复制代码

JSON_UNQUOTE 函数也是去掉双引号,等价于使用两个箭头

SELECT project ->> '$.name' as projectName FROM json_test
等价于
SELECT JSON_UNQUOTE(project -> '$.name') as projectName FROM json_test
等价于
SELECT JSON_UNQUOTE(JSON_EXTRACT(project, '$.name')) as projectName FROM json_test
复制代码

可以看出还是箭头函数方便

复杂JSON

多层复杂的 json 结构,提取想要的数据,也只需要按照key点下去即可

{
    "status": 1,
    "message": "SUCCESS",
    "data": {
        "list": [
            {
                "id": "1565510388254765086",
                "name": "测试1111",
                "object": [
                    {
                        "id": "1565510583118209025",
                        "tenderName": "客户1"
                    }
                ]
            },
            {
                "id": "1565504356392558665",
                "name": "测试2222",
                "object": [
                    {
                        "id": "1565504633934229506",
                        "tenderName": "客户2"
                    }
                ]
            }
        ]
    }
}
复制代码
SELECT other ->> '$.data.list[*].contractObject' 
FROM json_test 

- other 为表字段名
复制代码

如果不知道 key ,也可以用 星号 代替,但是也要知道是在第几层

SELECT other ->> '$**.contractObject' 
FROM json_test 
复制代码

在LambdaQueryChainWrapper中使用

在 MyBatis-Plus 中 使用 LambdaQueryChainWrapper 模糊查询 json 数据

new LambdaQueryChainWrapper<>(baseMapper)
                .like(StringUtils.isNotBlank(req.getTitle()), Test::getTitle, req.getTitle())
                .apply(StringUtils.isNotBlank(req.getRoles()), "roles ->> '$[*].name' LIKE CONCAT('%',{0},'%')", req.getRoles())
                .apply(StringUtils.isNotBlank(req.getProject()), "project -> '$.name' LIKE CONCAT('%',{0},'%')", req.getProject())
                .eq(req.getDeleted() != null, Test::getDeleted, req.getDeleted())
                .orderByDesc(Test::getCreatedAt)
                .list();
复制代码

使用 LambdaQueryChainWrapper 准确查询 json 数据

new LambdaQueryChainWrapper<>(baseMapper)
                .apply(StringUtils.isNotBlank(req.getRoles()), "JSON_CONTAINS(roles, JSON_OBJECT('name',{0}))", req.getRoles())
                .apply(StringUtils.isNotBlank(req.getProject()), "project -> '$.name' = {0}", req.getProject())
                .orderByDesc(Test::getCreatedAt)
                .list();
复制代码

使用 LambdaQueryChainWrapper 的话 ,一般都是用 apply 拼接自定义 sql

apply 是可以通过占位符的形式,传入多个参数的,也比较方便

LambdaQueryChainWrapper select 提取JSON数据

apply 是用做数据筛选用,那如果想 select 提取 json 中的数据呢

  • 首先需要在对应的实体类里新增一个字段,比如 roleName (不需要在表中创建该字段)
@TableField(value = "roles ->> '$[*].name'",
        insertStrategy = FieldStrategy.NEVER,
        updateStrategy = FieldStrategy.NEVER,
        select = false)
private String roleName;
复制代码

其中, value 对应的就是 select xxxx 形式

insertStrategy = FieldStrategy.NEVER 不执行插入

updateStrategy = FieldStrategy.NEVER 不执行更新

select = false 不让该字段出现在 select 

上述3个配置是为了不影响已有的增删改查,因为只是在实体类中新增了字段,没有在对应的表中增加该字段,可以根据自己的实际需求配置

  • 然后就可以在 LambdaQueryChainWrapper 中使用了
new LambdaQueryChainWrapper<>(baseMapper)
        .select(Test::getRoleName)
        .list();
复制代码

对应执行的 sql 如下

SELECT roles ->> '$[*].name' AS roleName FROM json_test
复制代码

这种方法可以在 select 中用 MySql 里的函数,比如常用的 SUM、MAX、COUNT 

@TableField(value = "SUM(money)",
        insertStrategy = FieldStrategy.NEVER,
        updateStrategy = FieldStrategy.NEVER,
        select = false)
private BigDecimal moneyCount;
复制代码

哎,就是不想在xml中写sql...(小声bb)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

MySql中json类型数据的查询以及在MyBatis-Plus中的使用 的相关文章

随机推荐

  • 如何创建React项目

    前言 构建React项目的几种方式 create react app 脚手架快速搭建 react 项目 推荐 yeoman 脚手架搭建 react 项目 webpack 一步一步构建 react 项目 脚手架是什么 脚手架是一种约定和规范
  • MOS管的作用及原理介绍

    MOS管的英文全称叫MOSFET Metal Oxide Semiconductor Field Effect Transistor 即金属氧化物半导体型场效应管 属于场效应晶体管中的绝缘栅型 因此 MOS管有时被称为场效应管 在一般电子电
  • Modbus RTU 工业通讯技术实现

    Modbus 是一个工业上常用的通讯协议 一种通讯约定 ModBus 协议是应用层报文传输协议 OSI 模型第7层 它定义了一个与通信层无关的协议数据单元 PDU 即PDU 功能码 数据域 ModBus 协议能够应用在不同类型的总线或网络
  • javaWeb中如何防止两个人同时操作同一条记录(限制单人操作),使用redis的解决方式

    最近在做demo的时候 碰到这么一个问题 当页面上同一角色有两个人登录的时候 他们同时操作统一条记录 简言之就是 同一记录同一时刻多人操作 这种情况在我的业务中回导致数据的冗余 干扰正常的程序运行 当时想到的解决办是锁表或者使用缓存 当然其
  • h0105 (10 分) c/c++

    c 代码 include
  • 互联网摸鱼日报(2023-03-29)

    互联网摸鱼日报 2023 03 29 InfoQ 热门话题 阿里再启组织变革 六大业务集团全面独立经营 张勇 具备条件的业务都可能独立上市 新一代Serverless事件中间件EventMesh正式毕业为Apache顶级项目 杭银消金基于
  • AVR单片机ATemga328P中断原理的介绍

    1 一AVR单片机中断原理的介绍 ATmega328P微控制器具有两个外部中断引脚 分别是INT0和INT1 外部中断0 INT0 它对应的引脚是PD2 数字引脚2 INT0可以用于响应外部信号的边沿触发 上升沿 下降沿或任意边沿 并触发相
  • 深聊全链路压测之:第二十讲

    日志隔离落地方案 1 引言 2 Demo预演 2 1 技术方案选型 2 2 Demo系统预演 2 3 扩展知识 日志分离 3 总结 1 引言 这节课 我们来学习如何基于微服务技术落地日志隔离 从第14讲开始 我们就详细的落地了基于微服务技术
  • linux服务器怎么添加路由,linux系统中添加路由的方法

    linux系统中添加路由的方法 发布时间 2020 06 17 11 38 59 来源 亿速云 阅读 95 作者 Leah 这篇文章将为大家详细讲解有关linux系统中添加路由的方法 小编觉得挺实用的 因此分享给大家做个参考 希望大家阅读完
  • Android webview实现h5视频全屏播放兼容Android7.0,自己添加webview库兼容全部版本

    2017年Android5 0主流机型webview的兼容性出现大问题导致很多公司app都不使用h5播放视频 关于谷歌自带的webview有各种兼容问题 最典型的的就是视频全屏onShowCustomView经常会点击不回调 可能是谷歌推崇
  • sonar scanner配置

    sonar scanner配置 这里记录如何配置sonar scanner扫描C C 项目代码 话不多说 先上官网链接 文章目录 sonar scanner配置 1 环境 1 1 SonarSource Build Wrapper 1 2
  • UDP及TCP通信对比讲解

    概述 TCP是面向连接的协议 也就是说在通信发送数据前 必须和对方建立连接 以数据流的模式传播 传输过程中不会有数据丢失 速率上比UDP要慢不少 适用于对数据准确性要求高 速度可以相对慢的场景 如发送或接收邮件 打电话 微信消息传输等等 U
  • 一看就懂的网络协议五层模型(一)

    我们每天使用互联网 你是否想过 它是如何实现的 全世界几十亿台电脑 连接在一起 两两通信 上海的某一块网卡送出信号 洛杉矶的另一块网卡居然就收到了 两者实际上根本不知道对方的物理位置 你不觉得这是很神奇的事情吗 互联网的核心是一系列协议 总
  • 【VSCode远程调试】【Python】Linux/Ubuntu远程服务器使用plt.show()没有反应

    plt模块结合numpy数组的可视化的常见用法 import matplotlib pyplot as plt img np array 1 2 3 4 plt imshow img plt show 以上写法在linux或者ubuntu系
  • mysql重命名一个表

    使用rename table rename table table1 altered to table 这里的sql语句会将table1 altered 重命名为table rename语句还可以将表移到另一个数据库中 rename tab
  • 14. 函数返回值为引用?

    函数返回值可以是引用吗 当然可以 只是在函数返回引用的时候需要注意几点 以下给出讨论 函数在返回值的时候 会产生一个临时变量作为函数返回值的副本 而函数在返回引用的时候 不会产生副本 那么既然是引用 那么到底是引用谁呢 首先 我们知道要清楚
  • 解决dubbo注册zookepper服务IP乱入问题的三种方式

    最近做一个项目引入了dubbo zookepper的分布式服务治理框架 在应用的发布的时候出现一个怪问题 zookepper服务是起在开发服务器192 168 23 180上 本机起应用服务提供者注册到192 168 23 180上的dub
  • 第一课:k8s介绍安装

    第一课 k8s介绍安装 tags golang 2019尚硅谷 categories K8s 文章目录 第一课 k8s介绍安装 第一节 K8s发展流程 1 1 相关概念 1 2 K8s发展历史 1 3 K8s特点 1 4 课程架构 需要掌握
  • 【廖雪峰python入门笔记】list_倒序访问

    倒序访问list 我们还是用一个list按分数从高到低表示出班里的3个同学 L Adam Lisa Bart 这时 老师说 请分数最低的同学站出来 要写代码完成这个任务 我们可以先数一数这个 list 发现它包含3个元素 因此 最后一个元素
  • MySql中json类型数据的查询以及在MyBatis-Plus中的使用

    表结构和初始数据 新建表结构 CREATE TABLE json test id int NOT NULL AUTO INCREMENT roles json DEFAULT NULL COMMENT 角色 project json DEF