springboot笔记示例七:mybiteplus框架mysql8新类型json集成

springboot笔记示例七:mysql8新类型json集成

###本文md文件下载地址

https://download.csdn.net/download/a254939392/89492142

md文件下载

建表SQL

CREATE TABLE `my_test` (`id` int unsigned NOT NULL AUTO_INCREMENT,`txt` json DEFAULT NULL,`txt_array` json DEFAULT NULL,PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=46 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

insert语句

插件非json插入时会自动校验格式会报错,{}或者[] [{}] 是被允许的。

对于 JSON 文档,KEY 名不能重复。

如果插入的值中存在重复 KEY,在 MySQL 8.0.3 之前,遵循 first duplicate key wins 原则,会保留第一个 KEY,后面的将被丢弃掉。从 MySQL 8.0.3 开始,遵循的是 last duplicate key wins 原则,只会保留最后一个 KEY。

INSERT INTO `my_test` ( `txt`, `txt_array` )VALUES( '{}', '[{}]' );
INSERT INTO `my_test` ( `txt`, `txt_array` )VALUES( '{}', '[]' );INSERT INTO `my_test` ( `txt`, `txt_array` ) VALUES( '{\"id\": 1, \"signUp\": 0, \"activityName\": \"撒旦士大夫\"}', NULL );
INSERT INTO `my_test` ( `txt`, `txt_array` )
VALUES ( '{\"id\": 1, \"signUp\": 0, \"activityName\": \"撒旦士大夫\"}', '{\"list\": [{\"id\": 1, \"signUp\": 0, \"activityName\": \"撒旦士大夫\"}, {\"id\": 2, \"signUp\": 0, \"activityName\": \"222撒旦士大夫\"}]}' );

select语句

-- column->path 语法糖,在实际使用的时候都会在底层自动转化为JSON_EXTRACT
-- column->path 等同于 JSON_EXTRACT(column, path) ,只能指定一个path。
--  select JSON_EXTRACT(txt,'$.activityName') from my_test == select txt->'$."activityName"' from my_testSELECT * FROM my_test WHERE txt->'$."activityName"' = '撒旦士大夫';
SELECT * FROM my_test WHERE txt->'$."activityName"' = '撒旦士大夫' and  txt->'$."type"' = 1
SELECT id,txt,txt_array FROM my_test WHERE txt -> '$.activityName' LIKE CONCAT('%','大夫','%') AND txt -> '$.type' = 1
SELECT * FROM my_test WHERE txt->'$."id"' = 1;
SELECT id, txt -> '$.*' AS nam11e FROM my_test

mybiteplus集成

json转换

本文采用最新fastjson2,目前mybatisplus并未支持fastjson2转换,所以需要自定义转换

//自定义fastjson2
@TableField(typeHandler = Fastjson2TypeHandler.class)
//mybatisplus 自带fastjosn直接使用
@TableField(typeHandler = FastjsonTypeHandler.class)
//mybatisplus 自带Jackson直接使用
@TableField(typeHandler = JacksonTypeHandler.class)
package com.config;import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.baomidou.mybatisplus.extension.handlers.AbstractJsonTypeHandler;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedJdbcTypes;
import org.apache.ibatis.type.MappedTypes;
/*** @Title: Fastjson2 实现 JSON 字段类型处理器* @Description: fastjson2转换类* @author: lihainan* @date: 2023年12月26日 下午1:22:04* @version: V1.0* @Copyright: nit逆天开源版权*/
@Slf4j
@MappedTypes({Object.class})
@MappedJdbcTypes(JdbcType.VARCHAR)
public class Fastjson2TypeHandler extends AbstractJsonTypeHandler<Object> {private final Class<?> type;public Fastjson2TypeHandler(Class<?> type) {if (log.isTraceEnabled()) {log.trace("FastjsonTypeHandler(" + type + ")");}Assert.notNull(type, "Type argument cannot be null");this.type = type;}@Overrideprotected Object parse(String json) {return JSON.parseObject(json, type);}@Overrideprotected String toJson(Object obj) {return JSON.toJSONString(obj);}
}

entity定义

package com.entity;import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.config.Fastjson2TypeHandler;
import com.dto.business.ActivityList;
import lombok.Data;
import java.io.Serializable;
@Data
@TableName(value = "my_test", autoResultMap = true)//autoResultMap = true 这个必须有哦
public class MyTest implements Serializable {/*** 主键*/@TableIdprivate Long id;/*** json类型转换为javabean*/@TableField(typeHandler = JacksonTypeHandler.class)private Activity txt;/*** json数组类型转换为javabean*/@TableField(typeHandler = Fastjson2TypeHandler.class)private List<Activity> txtArray;
}@Data
public class Activity implements Serializable {/*** 主键*/@TableIdprivate Long id;/*** 名称*/private String activityName;
}

curd

 	@Resourceprivate MyTestDao myTestDao;@GetMapping("/insert")public void insert() {Activity node = new Activity();node.setActivityName("撒旦士大夫");Activity node2 = new Activity();node2.setActivityName("222撒旦士大夫");List<Activity> list = Lists.newArrayList();list.add(node);list.add(node2);MyTest myTest = new MyTest();myTest.setTxt(node);myTest.setTxtArray(list);myTestDao.insert(myTest);}

select

MyTest test = new MyTest();
Activity node = new Activity();
node.setActivityName("大夫");
node.setType(1);
test.setTxt(node);LambdaQueryWrapper<MyTest> queryWrapper = Wrappers.lambdaQuery();
queryWrapper.apply(Objects.nonNull(test.getTxt()), "txt -> '$.activityName' LIKE CONCAT('%',{0},'%')", test.getTxt().getActivityName())//模糊查询.apply(Objects.nonNull(test.getTxt().getType()), "txt -> '$.type' = {0}", test.getTxt().getType());//精确查询List<MyTest> res = myTestDao.selectList(queryWrapper);

json索引优化

mysql官方说明地址:https://dev.mysql.com/doc/refman/8.0/en/create-table-secondary-indexes.html

json类型,无法直接创建索引,需要创建二级索引,创建虚拟列实现索引需求,

CREATE TABLE `my_test` (`id` int unsigned NOT NULL AUTO_INCREMENT,`txt` json DEFAULT NULL,`txt_array` json DEFAULT NULL,-- 虚拟列 需要设置表达式`js_id` int GENERATED ALWAYS AS (json_extract(`txt`,_utf8mb4'$.id')) VIRTUAL,PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=357 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;-- 增加虚拟列
ALTER TABLE `brm_pro_test`.`my_test` 
ADD COLUMN `sd` varchar AS (json_extract(`txt`,_utf8mb4'$.activityName')) VIRTUAL NULL 
-- 创建索引
ADD INDEX `index_key_id`(`js_id` ASC) USING BTREE;-- 使用虚拟列查询
explain
SELECT * FROM my_test WHERE js_id = 1;
+----+-------------+---------+------------+------+---------------+--------------+---------+------
| id | select_type | table   | partitions | type | possible_keys | key          | key_len | ref   | rows | filtered | Extra |
|  1 | SIMPLE      | my_test | NULL       | ref  | index_key_id  | index_key_id | 5       | const |  1 |   100.00 | NULL  |
+----+-------------+---------+------------+------+---------------+--------------+---------+--------- 无索引
mysql> explain SELECT * FROM my_test WHERE JSON_EXTRACT(txt,'$[1]') = 1;
+----+-------------+---------+------------+------+---------------+------+---------+------+------+
| id | select_type | table   | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra       |
+----+-------------+---------+------------+------+---------------+------+---------+------+------+
|  1 | SIMPLE      | my_test | NULL       | ALL  | NULL          | NULL | NULL    | NULL |  356 |   100.00 | Using where |
+----+-------------+---------+------------+------+---------------+------+---------+------+------+-
1 row in set (0.17 sec)

虚拟列:目前mybiteplus 只能使用动态sql 执行查询。实体无法映射字段的

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

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

相关文章

<电力行业> - 《第9课:输电(二)》

4 输送电能流程 输送电能总共有&#xff1a;发电站→升压变压器→高压输电线→降压变压器→用电单位等五个流程。 电力工业初期&#xff0c;发电厂建在电力用户附近&#xff0c;直接向用户送电&#xff0c;所以那个时候只有发电和用电两个环节。 随着电力生产规模和负荷中心规…

烧结刚玉砂轮片 磨具用晶谷低温陶瓷结合剂玻璃粉

晶谷CBN 砂轮磨具用低温陶瓷结合剂玻璃粉的一些特点如下&#xff1a; - 软化点&#xff1a;通常为450~650度&#xff1b; - 膨胀系数&#xff1a;50~12010-7&#xff1b; - 粒径&#xff1a;300~3000目&#xff08;可按要求订做&#xff09;&#xff1b; - 外观颜色&#xff…

h5兼容table ,如何实现h5在app内使用h5渲染table表格而且实现横屏预览?

压图地址 横屏div 通过css 实现 transform: rotate(90deg); transformOrigin: 50vw 50vw ; height: 100vw; width: 100vh;<divclass"popup-box":style"{transform: originSet 0 ? rotate(90deg) : ,transformOrigin: originSet 0 ? 50vw 50vw : ,height…

GuLi商城-商品服务-API-三级分类-删除-逻辑删除

注意&#xff1a;官方文档说logic配置可以省略&#xff0c;代码中直观些&#xff0c;配上吧 逻辑删除注解&#xff1a; 实体类字段上加逻辑删除注解&#xff1a; 启动nacos&#xff1a; 启动商品服务&#xff1a; postman测试&#xff1a; 数据库字段值改成了0&#xff0c;说明…

Linux----> tail、cat、more、head、less的用法详解

1.tail命令&#xff1a;用于查看文件的最后几行内容。 基本用法&#xff1a;tail [选项] [文件] 常用选项&#xff1a; -n <行数>&#xff1a;显示最后的 <行数> 行。-f&#xff1a;实时显示文件新增内容&#xff0c;通常用于查看日志文件。 示例&#xff1a;…

Python测试的艺术:深入理解单元测试与unittest框架应用

Python测试的艺术&#xff1a;深入理解单元测试与unittest框架应用 一、引言 在软件开发过程中&#xff0c;测试是确保软件质量的关键环节。Python作为一种流行的编程语言&#xff0c;其测试体系也非常成熟和强大。其中&#xff0c;单元测试是测试体系中最基础、最常用的一种…

数据恢复篇:如何在没有备份的情况下从恢复已删除的照片

许多用户更喜欢将他们的私人照片保存在他们的 Android 设备上的一个单独的安全空间中&#xff0c;以确保他们的记忆不仅被存储&#xff0c;而且受到保护。这就是“安全文件夹”功能派上用场的地方。您可以使用 PIN 码、密码、指纹或图案锁定此文件夹&#xff0c;即使您的设备落…

Linux Docker Squid:构建自己的代理服务器

基础环境 ubuntu: docker docker-compose 1.准备环境 安装Docker和Docker Compose # 安装Docker sudo apt-get update sudo apt-get install docker.io# 安装Docker Compose sudo apt-get install docker-compose2.创建一个Dockerfile来构建Squid代理服务器的Docker镜像。 …

从Oracle自定义函数和存储过程案例学习PL/SQL的使用

一、什么是PL/SQL PL/SQL&#xff08;Procedural Language/Structured Query Language&#xff09; 是Oracle数据库对SQL的扩展&#xff0c;它在SQL的基础上增加了过程化编程语言的元素&#xff0c;如变量、条件语句、循环语句、异常处理等。这使得PL/SQL不仅可以用于查询数据&…

[小试牛刀-习题练]《计算机组成原理》之数据信息的表示、运算方法与运算器

【数据信息的表示运算方法与运算器】 1、【机器码转换】X-0.11111111&#xff0c;X的补码是 1.00000001 。 最高位符号位为负值&#xff1a; 反码法——绝对值按位取反末位加一&#xff0c;1.000000000.000000011.00000001扫描法——从右往左找到第一个为1的&#xff…

常用字符串方法<python>

导言 在python中内置了许多的字符串方法&#xff0c;使用字符串方法可以方便快捷解决很多问题&#xff0c;所以本文将要介绍一些常用的字符串方法。 目录 导言 string.center(width[,fillchar]) string.capitalize() string.count(sub[,start[,end]]) string.join(iterabl…

ffmpeg编码图象时报错Invalid buffer size, packet size * < expected frame_size *

使用ffmpeg将单个yuv文件编码转为jpg或其他图像格式时&#xff0c;报错&#xff1a; Truncating packet of size 11985408 to 3585 [rawvideo 0x1bd5390] Packet corrupt (stream 0, dts 1). image_3264_2448_0.yuv: corrupt input packet in stream 0 [rawvideo 0x1bd7c60…

在本地和Linux之间传输文件

1.打开本地的cmd窗口 2. 然后按这个链接的说法在cmd中远程连接Linux&#xff08;技术|如何在 Linux 中使用 sFTP 上传或下载文件与文件夹&#xff09; 3. 看这个链接里面的sftp命令进行本地和Linux之间的文件互传 &#xff08;https://www.cnblogs.com/niuben/p/13324099.htm…

【嵌入式CLion】进阶调试——WSL下的Linux体验

说明&#xff1a; 1&#xff0c;这里所指的嵌入式其实是指嵌入式微控制器MCU&#xff0c;即单片机 2&#xff0c;万事开头难&#xff0c;本文目前提供了WSL工具链的搭建&#xff0c;后面会持续更新 一、启用RTOS集成 在搭建WSL工具链之前&#xff0c;先讲一下集成的RTOS功能&a…

D-MAX纠偏软件Fife MAX Terminal软件MAX-Oi软件

D-MAX纠偏软件Fife MAX Terminal软件MAX-Oi软件

无理数的本质:一维无法理解更高维

无理数是那些不能表示为两个整数的比的数&#xff0c;其小数部分是无限不循环的&#xff0c;常见的无理数有 π、√2 等。 如果从更本质一点的角度来理解&#xff0c;无理数的出现是因为一维无法完全理解更高维。更高维的“长度”映射到一维&#xff0c;可能出现映射不完全的情…

python r, b, u, f 前缀详解

1、r前缀 一般来说&#xff0c;\n’是一个换行符&#xff0c;是一个字符串&#xff1b;而加上r为前缀后&#xff0c;不会以任何特殊方式处理反斜杠。因此&#xff0c;r"\n" 是包含 ‘\’ 和 ‘n’ 的双字符字符串&#xff1b;示例如下&#xff1a; >>> pr…

SpringBoot的自动配置核心原理及拓展点

Spring Boot 的核心原理几个关键点 约定优于配置&#xff1a; Spring Boot 遵循约定优于配置的理念&#xff0c;通过预定义的约定&#xff0c;大大简化了 Spring 应用程序的配置和部署。例如&#xff0c;它自动配置了许多常见的开发任务&#xff08;如数据库连接、Web 服务器配…

8080时序驱动TFT显示屏 驱动IC GC9307

8080时序总共有控制线 CS片选线 DC(命令数据控制线) RD读控制线 WR写控制线 和N条数据线。 控制底层代码如下; 写读代码,读的代码反过来就行 inline void TFT8080WriteDat(unsigned char dat) {CS_L;//开始片选DC_H;//写数据 // RD_H;//禁止读WR_H;//禁止写WR_L;//写入…

低空经济腾飞:无人机空域申请流程及策略

一、引言 随着低空经济的快速发展&#xff0c;无人机已广泛应用于各个领域&#xff0c;包括航拍、物流、农业、科研等。为了保障飞行安全、维护空中交通秩序&#xff0c;各国纷纷出台了无人机飞行管理规定。本文将详细介绍无人机空域申请的流程及策略&#xff0c;帮助无人机运…