mysql json字段使用以及常用json函数,配合springBoot和mybatis-plus简化开发

Mysql JSON 类型分享

Mysql json字段了解:

MySQL 中的 JSON 类型是一种用于存储和处理 JSON(JavaScript Object Notation)数据的数据类型。JSON 是一种轻量级的数据交换格式,常用于表示结构化的数据。MySQL 的 JSON 类型提供了以下几个用处和好处:

  1. 存储和查询复杂的数据结构:JSON 类型允许你将复杂的数据结构以 JSON 格式存储在数据库中,例如嵌套的对象、数组等。这使得存储和查询具有复杂结构的数据变得更加方便和灵活。

  2. 简化数据模型:使用 JSON 类型可以将多个相关的属性组合成一个 JSON 对象进行存储,而不需要创建多个表和关联关系。这样可以简化数据模型,减少表的数量,提高数据的可读性和维护性。

  3. 动态模式:JSON 类型允许你在不改变表结构的情况下,动态地添加、删除或修改 JSON 对象中的属性。这对于需要频繁变化的数据模型非常有用,避免了频繁的表结构修改。

  4. 简化应用层逻辑:通过使用 JSON 类型,你可以将复杂的数据结构直接存储在数据库中,而不需要在应用层进行手动的序列化和反序列化操作。这简化了应用程序的逻辑,减少了开发和维护的工作量。

  5. 快速查询和索引:MySQL 提供了一些针对 JSON 类型的查询函数和操作符,使得对 JSON 数据进行检索和过滤变得更加高效。此外,你还可以为 JSON 字段创建索引,提高查询性能。

JSON 类型在 MySQL 中的支持从版本 5.7.8 开始引入。在此之前的版本中,可以使用字符串类型(如 VARCHAR)来存储 JSON 数据,但没有专门的 JSON 类型和相关的 JSON 函数。

从 MySQL 5.7.8 开始,你可以使用 JSON 类型来存储和操作 JSON 数据。JSON 类型提供了一些内置的函数和操作符,用于处理 JSON 数据,例如提取、修改和查询 JSON 字段中的数据。

总的来说,MySQL 的 JSON 类型提供了一种灵活、方便和高效地存储和处理复杂结构的数据的方式,简化了数据模型和应用层逻辑,并提高了查询性能。

一、创建表,以及插入数据

建表:

CREATE TABLE file_detail ( file_id varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '文件编号', info json DEFAULT NULL COMMENT '文件详情', describ varchar(1024) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '文件描述', create_time datetime DEFAULT NULL COMMENT '创建时间', update_time datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', finalize char(2) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci GENERATED ALWAYS AS (ifnull(json_unquote(json_extract(info,utf8mb4'$.finalize')),utf8mb4'')) VIRTUAL, PRIMARY KEY (file_id) USING BTREE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC;

插入数据:

INSERT INTO file_detail (file_id,info,describ,create_time,update_time) VALUES ( 'test1', JSON_OBJECT( 'tag_array',JSON_ARRAY(JSON_OBJECT('tag_id','1','tag_name','双十一'),JSON_OBJECT('tag_id','2','tag_name','双十二')), 'brand_array',JSON_ARRAY(JSON_OBJECT('brand_id','1','brand_name','roopy')), 'ocr_array',JSON_ARRAY('roopy','护手霜'),

'link','www.roopy.com',

'finalize','Y' ), '润培双十一', NOW(),NOW() );

二:JSON类型的常用函数

插入数据表的JSON函数:
  1. JSON_ARRAY JSON数组

  2. JSON_OBJECT JSON对象

JSON类型的查询函数:

1.JSON_EXTRACT用于从 JSON 值中提取指定路径的数据。

语法:

JSON_EXTRACT(json_column, path)

示例:

SELECT JSON_EXTRACT(info, "$.link") as link FROM file_detail WHERE file_id = 'test11';

在上面的示例中,假设你有一个名为 my_table 的表,其中包含一个名为 data 的 JSON 列。JSON_EXTRACT 函数用于从 data 列中提取 name 属性的值。

但是这个获取的值是json的值,还有双引号。

2.JSON_UNQUOTE去除双引号,一般和JSON_EXTRACT 配合使用

实例:

SELECT JSON_UNQUOTE(JSON_EXTRACT(info, "$.link"))  as link FROM file_detail WHERE file_id = 'test11';

MySQL 还提供了 ->> 表达式,使用该表达式可以实现与JSON_UNQUOTE(JSON_EXTRACT相同的功能需求

示例:

SELECT info ->> '$.link' AS link FROM file_detail WHERE file_id = 'test11';

3.JSON_CONTAINS用于检查 JSON 值是否包含指定的键或值。

语法:

JSON_CONTAINS(json_column, value, path)

示例:

SELECT * FROM file_detail WHERE JSON_CONTAINS(info,'"护手霜"','$.ocr_array');

查询所有文字识别中包含护手霜的文件详情

4.JSON_SEARCH用于查找 JSON 值中指定键或值的路径。

JSON_SEARCH(json_doc, one_or_all, search_str, escape_char, path)

参数解释如下:

  1. json_doc:要搜索的 JSON 文档或 JSON 字符串。

  2. one_or_all

    :指定搜索模式,可以是以下两个值之一:

    • 'one':返回第一个匹配项的路径。

    • 'all':返回所有匹配项的路径,以逗号分隔。

  3. search_str:要搜索的值,可以是字符串、数字、布尔值等。

  4. escape_char(可选):用于转义搜索字符串中的特殊字符的转义字符。如果不需要转义,则可以将该参数设置为 NULL

  5. path(可选):指定要搜索的 JSON 路径。如果不提供该参数,则将在整个 JSON 文档中进行搜索。

请注意,JSON_SEARCH 函数返回的是一个字符串,表示匹配的路径。如果找不到匹配项,则返回 NULL

示例:

SELECT JSON_SEARCH(info, 'one','护手霜', null,'$.ocr_array') FROM file_detail WHERE file_id = 'test11';

查找表中id为test11 ocr_array中为护手霜的路径

JSON类型的修改函数:
  1. JSON_SET(json_doc, path, val[, path, val]...):用于在 JSON 文档中设置指定路径的值。它接受多个路径-值对作为参数,并返回更新后的 JSON 文档。如果路径已存在,则更新其对应的值;如果路径不存在,则创建新的路径并设置对应的值。

    示例:

    UPDATE file_detail
    SET info = JSON_SET(info, '$.link', 'www.hans.com')
    WHERE file_id = 'test111';

  2. JSON_INSERT(json_doc, path, val[, path, val]...):用于在 JSON 文档中插入指定路径的值。它接受多个路径-值对作为参数,并返回更新后的 JSON 文档。如果路径已存在,则不进行任何操作。

    示例:

    UPDATE file_detail 
    SET info = JSON_INSERT(info, '$.finalize', 'N')
    WHERE file_id = 'test1'
  3. JSON_ARRAY_INSERT:跟上面类似,用于插入数组

    UPDATE file_detail
    SET info = JSON_ARRAY_INSERT(info, '$.tag_array[1]', JSON_OBJECT("tag_id","2","tag_name","双十二"))
    WHERE file_id = 'test111';

4.JSON_REMOVE(json_doc, path[, path]...):用于从 JSON 文档中移除指定路径的值。它接受一个或多个路径作为参数,并返回更新后的 JSON 文档。

示例:

UPDATE file_detail 
SET info = JSON_REMOVE(info, '$.tag_array[1]')
WHERE file_id = 'test111'

删除掉tag标签中的第二个标签

结合上面的几个函数:

1.修改标签时,更新所有使用该标签的标签名称

UPDATE file_detail SET info =JSON_SET(info,JSON_UNQUOTE(JSON_SEARCH(info, 'one', #{oldName}, NULL, '$.tag_array[].tag_name')),#{newName}) WHERE JSON_SEARCH(info, 'one', #{oldName}, NULL, '$.tag_array[].tag_name') IS NOT NULL

2.查询使用该标签的文件数量

select count() from file_detail where JSON_SEARCH(info, 'one', #{tagId}, NULL, '$.tag_array[].tag_id') IS NOT NULL

三、JSON类型字段结合Mybatis_plus

domain类:

@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
public class FileDetail implements Serializable {
​private static final long serialVersionUID = 5006880643442005239L;/*** 文件编号*/@TableId(value = "file_id")private String fileId;
​/*** 文件详情*/
//    @TableField(typeHandler = FileDetailInfoTypeHandler.class)@TableField(typeHandler = FastjsonTypeHandler.class)private FileDetailInfo info;
​/*** 文件描述*/private String describ;
​/*** 是否定稿*/private String finalize;
​/*** 创建时间*/@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")private LocalDateTime createTime;
​/*** 更新时间*/@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")private LocalDateTime updateTime;
​
​
​
​
}

mybatis 本身不支持json的转化,所以我们在mybatis处理的时候手动修改

BaseTypeHandler 是 MyBatis 中的一个抽象类,用于处理数据库字段与 Java 对象之间的类型转换。它包含了以下四个抽象方法:

  1. setParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType):将 Java 对象转换为数据库字段,并设置到 PreparedStatement 对象中。其中,ps 是 PreparedStatement 对象,i 是参数的位置,parameter 是要设置的 Java 对象,jdbcType 是数据库字段的 JDBC 类型。

  2. getResult(ResultSet rs, String columnName):从 ResultSet 对象中获取指定列名的数据库字段,并将其转换为相应的 Java 对象。返回值为转换后的 Java 对象。

  3. getResult(ResultSet rs, int columnIndex):从 ResultSet 对象中获取指定列索引的数据库字段,并将其转换为相应的 Java 对象。返回值为转换后的 Java 对象。

  4. getResult(CallableStatement cs, int columnIndex):从 CallableStatement 对象中获取指定列索引的数据库字段,并将其转换为相应的 Java 对象。返回值为转换后的 Java 对象。

    我们可以继承这个类,重写这几个方法来满足一些个性化的需求,比如时间格式转换,类型转换,加密解密,自定义数据格式化(比如我们的fen->yuan)等等

新写一个类,并且重写这四个方法,在特定的字段上使用这个新的Handler:(当然我们可以直接使用mybatis-plus提供的FastJson直接在字段上进行注解:@TableField(typeHandler = FastjsonTypeHandler.class))

import cn.hutool.core.util.CharUtil; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.nala.test.domain.FileDetailInfo; import org.apache.commons.lang3.StringUtils; import org.apache.ibatis.type.*; import org.springframework.stereotype.Repository;

import java.sql.CallableStatement; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.Objects;

/** * ** Fastjson TypeHandler**,用于将对象转换为 JSON *字符串 * * @author** *NALA * / *public class AbstractObjectTypeHandler<T> extends BaseTypeHandler<T> { */ * * *定义设置参数时,该如何把Java类型的参数转换为对应的数据库类型 * * * @param** *ps * * @param** *i * * @param** *parameter * * @param** *jdbcType * * @throws** SQLException * **/ * @Override public void setNonNullParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException { if (Objects.nonNull(parameter)) { ps.setString(i, JSON.toJSONString*(parameter)); } }

*/** * * *定义通过字段名称获取字段数据时,如何把数据库类型转换为对应的Java类型 * * * @param** *rs * * @param** *columnName * * @return ** * @throws** *SQLException * **/ * @Override ​ public T getNullableResult(ResultSet rs, String columnName) throws SQLException { ​ return deserialize(rs.getString(columnName)); ​ }

*/** * * *定义通过字段索引获取字段数据时,如何把数据库类型转换为对应的Java类型 * * * @param** *rs * * @param** *columnIndex * * @return ** * @throws** *SQLException * **/ * @Override ​ public T getNullableResult(ResultSet rs, int columnIndex) throws SQLException { ​ return deserialize(rs.getString(columnIndex)); ​ }

*/** * * *定义调用存储过程后,如何把数据库类型转换为对应的Java类型 * * * @param** *cs * * @param** *columnIndex * * @return ** * @throws** *SQLException * **/ * @Override ​ public T getNullableResult(CallableStatement cs, int columnIndex) throws SQLException { ​ return deserialize(cs.getString(columnIndex)); ​ }

*/** * * *数据反序列化 * * * @param** data * * @return ** **/ * private T deserialize(String data) { ​ if (StringUtils.isEmpty(data)) { ​ return null; ​ } ​ Class<T> clazz = (Class<T>) getRawType(); ​ if (CharUtil.BRACKET_START* == data.charAt(0)) { ​ return JSONArray.parseObject(data, clazz); ​ } else { ​ return JSONObject.parseObject(data, clazz); ​ } ​ }

这是一个公共类,其他如果有需求,继承这个类就行了

public class FileDetailInfoTypeHandler extends AbstractObjectTypeHandler<FileDetailInfo> {

}

注意:我们重新需要在配置中定义mybatis_plus扫描的位置让其生效

#mybatis—plus *自定handler的扫描路径 *mybatis-plus: type-handlers-package: com.nala.test.handler

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/92722.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Fragment之间进行通信的最佳实现方式

前言 在Android应用程序中&#xff0c;片段&#xff08;Fragments&#xff09;是一种组件&#xff0c;用于构建灵活且可重用的用户界面。然而&#xff0c;当在应用程序中使用多个片段时&#xff0c;它们之间的通信变得非常重要。本文将介绍在Android应用程序中实现片段之间和片…

Polygon Miden:扩展以太坊功能集的ZK-optimized rollup

1. 引言 Polygon Miden定位为zkVM&#xff0c;定于2023年Q4上公开测试网。 zk、zkVM、zkEVM及其未来中指出&#xff0c;当前主要有3种类型的zkVM&#xff0c;括号内为其相应的指令集&#xff1a; mainstream&#xff08;WASM, RISC-V&#xff09;EVM&#xff08;EVM bytecod…

Java:正则表达式的命名捕获组

命名捕获组格式 (?<year>.*)-(?<month>.*)-(?<date>.*)完整示例 package com.example.demo;import java.util.regex.Matcher; import java.util.regex.Pattern;public class RegexTests {public static void main(String[] args) {String text "2…

3.css的各种选择器

元素选择器 body中的形式 <span class"cls" id"time">2023年03月02日 21:50</span> <span class"cls">央视网</span>head中的形式 <style>h1 {color: #4D4F53;}/* 元素选择器 */span {color: red;} }</styl…

Kubernetes 学习总结(38)—— Kubernetes 与云原生的联系

一、什么是云原生&#xff1f; 伴随着云计算的浪潮&#xff0c;云原生概念也应运而生&#xff0c;而且火得一塌糊涂&#xff0c;大家经常说云原生&#xff0c;却很少有人告诉你到底什么是云原生&#xff0c;云原生可以理解为“云”“原生”&#xff0c;Cloud 可以理解为应用程…

C++:stl:list的常用接口及其模拟实现

本文主要介绍c&#xff1a;stl中list常用接口的功能及使用方法&#xff0c;比较list与vector的区别&#xff0c;并对list的常用接口进行模拟实现。 目录 一、list的介绍和使用 1.list介绍 2.list使用 1.list的构造 2.list iterator的使用 3.list 容量相关 4.list元素访…

[NOIP2011 提高组] 选择客栈

[NOIP2011 提高组] 选择客栈 题目描述 丽江河边有 n n n 家很有特色的客栈&#xff0c;客栈按照其位置顺序从 1 1 1 到 n n n 编号。每家客栈都按照某一种色调进行装饰&#xff08;总共 k k k 种&#xff0c;用整数 0 ∼ k − 1 0 \sim k-1 0∼k−1 表示&#xff09;&am…

机器学习——seaborn实用画图方法简介

0、seaborn简介: 前言:下面的总结只是介绍seaborn有哪些方法和属性,至于具体使用,通过下面给出的名称稍作查找即可。重点应该关注本文介绍的seaborn的使用方法seaborn与机器学习的关系: 知识图谱 0.1、了解即可的知识: seaborn:在matplotlib的基础上画一些更好看的图,在…

Mysql集群高可用架构MHA

Mysql集群高可用架构MHA 一、MHA概述1.1、 MHA 是什么1.2、 MHA 的组成1.3、 MHA 的特点 二、MHA高可用实例2.1、配置主从复制2.1、 安装 MHA 软件2.2、故障模拟2.3、故障修复 一、MHA概述 1.1、 MHA 是什么 MHA&#xff08;MasterHigh Availability&#xff09;是一套优秀的M…

计算机毕设 大数据全国疫情数据分析与3D可视化 - python 大数据

文章目录 0 前言1 课题背景2 实现效果3 设计原理4 部分代码5 最后 0 前言 &#x1f525; 这两年开始毕业设计和毕业答辩的要求和难度不断提升&#xff0c;传统的毕设题目缺少创新和亮点&#xff0c;往往达不到毕业答辩的要求&#xff0c;这两年不断有学弟学妹告诉学长自己做的…

【C++刷题笔记】螺旋矩阵的两种写法

螺旋矩阵有两种判断大循环结束的方式&#xff0c;第一种是判断需要循环多少次&#xff0c;奇数的话需要额外处理&#xff1b;第二种通过取多少个数判断&#xff0c;不需要额外处理 方法一&#xff1a; class Solution { public:vector<int> spiralOrder(vector<vect…

OpenCV之直线曲线拟合

直线拟合fitLine void fitLine( InputArray points, OutputArray line, int distType,double param, double reps, double aeps ); points:二维点的数组或vector line:输出直线,Vec4f (2d)或Vec6f (3d)的vector distType:距离类型 param:距离参数 reps:径向的精度参数 a…

【2023集创赛】加速科技杯三等奖作品:私密性高精度刷手身份认证系统

本文为2023年第七届全国大学生集成电路创新创业大赛&#xff08;“集创赛”&#xff09;加速科技杯三等奖作品分享&#xff0c;参加极术社区的【有奖征集】分享你的2023集创赛作品&#xff0c;秀出作品风采&#xff0c;分享2023集创赛作品扩大影响力&#xff0c;更有丰富电子礼…

Centos7 安装mysql 5.7

Centos7 安装mysql 5.7 准备工作 centos7 服务器 xshell 安装教程 安装并配置 在安装MySQL之前&#xff0c;我们应该确保系统已经更新到最新的软件包和安全补丁。打开终端&#xff0c;输入以下命令来更新系统 yum update为了方便安装MySQL&#xff0c;我们需要下载并安装…

【数据结构】排序之插入排序和选择排序

&#x1f525;博客主页&#xff1a;小王又困了 &#x1f4da;系列专栏&#xff1a;数据结构 &#x1f31f;人之为学&#xff0c;不日近则日退 ❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ 目录 一、排序的概念及其分类 &#x1f4d2;1.1排序的概念 &#x1f4d2;1.2排序…

HTML详细基础(二)文件路径

目录 一.相对路径 二.绝对路径 三.超链接标签 四.锚点链接 首先&#xff0c;扩展一些HTML执行的原理&#xff1a; htmL(hypertext markup Language) 是一种规范&#xff08;或者说是一种标准&#xff09;&#xff0c;它通过标记符&#xff08;tag&#xff09;来标记要显示…

【FreeRTOS】FreeRTOS移植stm32详细步骤介绍

我在查找FreeRTOS移植的相关教程特别少&#xff0c;所以想非常详细的介绍FreeRTOS移植stm32详细步骤&#xff0c;包括源码的下载&#xff0c;源码介绍&#xff0c;系统移植&#xff0c;代码验证等&#xff0c;每一步都有对应的介绍和解释&#xff0c;希望可以帮助到你们。 文章…

openGauss学习笔记-84 openGauss 数据库管理-内存优化表MOT管理-内存表特性-MOT部署服务器优化:x86

文章目录 openGauss学习笔记-84 openGauss 数据库管理-内存优化表MOT管理-内存表特性-MOT部署服务器优化&#xff1a;x8684.1 BIOS84.2 操作系统环境设置84.3 网络 openGauss学习笔记-84 openGauss 数据库管理-内存优化表MOT管理-内存表特性-MOT部署服务器优化&#xff1a;x86 …

使用van-dialog二次封装微信小程序模态框

由于微信小程序的wx.showModal不支持富文本内容&#xff0c;无法实现更灵活的展示效果&#xff0c;故需要进行二次封装 实现思路&#xff1a;使用van-dialog以及微信小程序的rich-text实现 代码如下&#xff1a; // index.wxml <van-dialoguse-slottitle"提示"s…

基于vue+Element Table Popover 弹出框内置表格的封装

文章目录 项目场景&#xff1a;实现效果认识组件代码效果分析 封装&#xff1a;代码封装思路页面中使用 项目场景&#xff1a; 在选择数据的时候需要在已选择的数据中对比选择&#xff0c;具体就是点击一个按钮&#xff0c;弹出一个小的弹出框&#xff0c;但不像对话框那样还需…