MyBatis-Plus LambdaQuery 高级用法:JSON 路径查询与条件拼接的全场景解析
目录
1. 查询 JSON 字段中的特定值
2. 动态查询 JSON 字段中的值
3. 查询 JSON 数组中的值
4. 查询 JSON 字段中的嵌套对象
5. 结合其他条件查询 JSON 字段
6. 使用类型处理器简化 JSON 查询
6.1 创建自定义 JSON 类型处理器
6.2 在实体类中指定自定义类型处理器
示例代码
6.3 配置类型处理器包(可选)
6.4 使用自定义类型处理器
7. 使用内置的 JacksonTypeHandler 或 FastjsonTypeHandler
1. 查询 JSON 字段中的特定值
假设有一个表 user
,其中包含一个 JSON 字段 info
,存储了用户的一些额外信息。如果要查询 info
字段中 age
大于 20 的用户,可以使用以下代码:
LambdaQueryWrapper<User> queryWrapper = Wrappers.lambdaQuery();
queryWrapper.apply("JSON_EXTRACT(info, '$.age') > {0}", 20);
List<User> users = userMapper.selectList(queryWrapper);
这里通过 apply
方法嵌入了 MySQL 的 JSON_EXTRACT
函数。
2. 动态查询 JSON 字段中的值
如果需要根据动态条件查询 JSON 字段中的值,例如根据用户输入的条件查询 info
字段中 gender
为 "male"
的用户,可以这样实现:
LambdaQueryWrapper<User> queryWrapper = Wrappers.lambdaQuery();
if ("male".equals(gender)) {queryWrapper.apply("JSON_EXTRACT(info, '$.gender') = {0}", "\"male\"");
}
List<User> users = userMapper.selectList(queryWrapper);
这种方式可以根据条件动态添加查询语句。
3. 查询 JSON 数组中的值
假设 info
字段是一个 JSON 数组,存储了用户的多个兴趣爱好,要查询兴趣爱好中包含 "reading"
的用户:
LambdaQueryWrapper<User> queryWrapper = Wrappers.lambdaQuery();
queryWrapper.apply("JSON_CONTAINS(info, {0})", "\"reading\"");
List<User> users = userMapper.selectList(queryWrapper);
这里使用了 MySQL 的 JSON_CONTAINS
函数。
4. 查询 JSON 字段中的嵌套对象
如果 JSON 字段中包含嵌套对象,例如 info
字段中有一个 address
对象,要查询 address
中的 city
为 "Beijing"
的用户:
LambdaQueryWrapper<User> queryWrapper = Wrappers.lambdaQuery();
queryWrapper.apply("JSON_EXTRACT(info, '$.address.city') = {0}", "\"Beijing\"");
List<User> users = userMapper.selectList(queryWrapper);
通过指定 JSON 路径,可以查询嵌套对象中的值。
5. 结合其他条件查询 JSON 字段
可以将 JSON 字段的查询与其他普通字段的查询条件结合使用。例如,查询状态为 "active"
且 info
字段中 age
大于 20 的用户:
LambdaQueryWrapper<User> queryWrapper = Wrappers.lambdaQuery();
queryWrapper.eq(User::getStatus, "active").apply("JSON_EXTRACT(info, '$.age') > {0}", 20);
List<User> users = userMapper.selectList(queryWrapper);
这种方式可以灵活地组合多种查询条件。
6. 使用类型处理器简化 JSON 查询
从 MyBatis-Plus 3.5.3.2 版本开始,可以在 Wrapper 查询中直接使用类型处理器。例如,假设有一个自定义的 JSON 类型处理器 UserInfoTypeHandler
,可以这样使用:
LambdaQueryWrapper<User> queryWrapper = Wrappers.lambdaQuery();
queryWrapper.apply("info = {0, typeHandler=" + UserInfoTypeHandler.class.getCanonicalName() + "}", "{\"age\":20,\"gender\":\"male\"}");
List<User> users = userMapper.selectList(queryWrapper);
通过类型处理器,可以更方便地处理 JSON 数据
6.1 创建自定义 JSON 类型处理器
自定义的 JSON 类型处理器需要继承 BaseTypeHandler
或 AbstractJsonTypeHandler
等内置类型处理器,并实现相关方法。
示例代码
以下是一个基于 Jackson 的自定义 JSON 类型处理器示例:
import com.baomidou.mybatisplus.extension.handlers.AbstractJsonTypeHandler;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedJdbcTypes;
import org.apache.ibatis.type.MappedTypes;import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;@MappedTypes({Object.class}) // 指定支持的 Java 类型
@MappedJdbcTypes(JdbcType.VARCHAR) // 指定对应的 JDBC 类型
public class CustomJsonTypeHandler<T> extends AbstractJsonTypeHandler<T> {private static final ObjectMapper objectMapper = new ObjectMapper();public CustomJsonTypeHandler(Class<T> type) {super(type);}@Overrideprotected T parse(String json) {try {return objectMapper.readValue(json, getType());} catch (Exception e) {throw new RuntimeException("Failed to parse JSON", e);}}@Overrideprotected String toJson(T obj) {try {return objectMapper.writeValueAsString(obj);} catch (Exception e) {throw new RuntimeException("Failed to serialize object to JSON", e);}}
}
6.2 在实体类中指定自定义类型处理器
在实体类中,通过 @TableField
注解指定自定义的类型处理器。
示例代码
假设有一个 User
实体类,其中 info
字段是一个 JSON 字段,存储用户的一些额外信息:
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;@Data
@TableName(value = "user", autoResultMap = true)
public class User {private Long id;private String name;@TableField(typeHandler = CustomJsonTypeHandler.class)private UserInfo info; // UserInfo 是一个自定义的 Java 类
}
6.3 配置类型处理器包(可选)
如果自定义的类型处理器不在默认扫描路径下,可以在 application.yml
中指定类型处理器的包路径:
mybatis-plus:type-handlers-package: com.yourpackage.handler
6.4 使用自定义类型处理器
在 MyBatis-Plus 的增删改查操作中,自定义的类型处理器会自动生效。例如:
User user = new User();
user.setName("Alice");
user.setInfo(new UserInfo("Beijing", 25)); // 设置 JSON 字段
userMapper.insert(user);// 查询时,info 字段会自动解析为 UserInfo 对象
User queriedUser = userMapper.selectById(user.getId());
System.out.println(queriedUser.getInfo().getCity()); // 输出 Beijing
通过以上步骤,你可以在 MyBatis-Plus 中使用自定义的 JSON 类型处理器来处理数据库中的 JSON 字段
7. 使用内置的 JacksonTypeHandler
或 FastjsonTypeHandler
MyBatis-Plus 提供了内置的 JSON 类型处理器,如 JacksonTypeHandler
和 FastjsonTypeHandler
,可以直接将 JSON 字段映射为 JSONObject
或其他 JSON 类型。
示例代码
假设有一个表 user
,其中 info
是一个 JSON 字段,存储用户的一些额外信息。在实体类中,可以这样配置:
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;@Data
@TableName("user")
public class User {private Long id;private String name;@TableField(typeHandler = JacksonTypeHandler.class)private JSONObject info; // 使用 JSONObject
}
在 MyBatis-Plus 的增删改查操作中,info
字段会自动被解析为 JSONObject
相关文章:
MyBatis-Plus LambdaQuery 高级用法:JSON 路径查询与条件拼接的全场景解析
目录 1. 查询 JSON 字段中的特定值 2. 动态查询 JSON 字段中的值 3. 查询 JSON 数组中的值 4. 查询 JSON 字段中的嵌套对象 5. 结合其他条件查询 JSON 字段 6. 使用类型处理器简化 JSON 查询 6.1 创建自定义 JSON 类型处理器 6.2 在实体类中指定自定义类型处理器 示例…...

[AI绘画]sd学习记录(一)软件安装以及文生图界面初识、提示词写法
目录 目录一、安装软件二、文生图各部分模块 1. 下载新模型 & 画出第一张图2. 提示词输入 2.1 设置2.2 扩展模型2.3 扩展模型权重调整2.4 其他提示词输入2.5 负向提示词2.6 生成参考 3. 采样方法4. 噪声调度器5. 迭代步数6. 提示词引导系数 一、安装软件 软件安装&…...

SpringBoot(八) --- SpringBoot原理
目录 一、配置优先级 二、Bean的管理 1. Bean的作用域 2. 第三方Bean 三、SpringBoot原理 1. 起步依赖 2. 自动配置 3. 自动配置原理分析 3.1 源码解析 3.2 Conditional 一、配置优先级 SpringBoot项目当中支持三类配置文件: application.properties a…...
SpringBoot自动化部署全攻略:CI/CD高效实践与避坑指南
SpringBoot自动化部署全攻略:CI/CD高效实践与避坑指南 🚀 一、现代化部署方案选型对比 1. 主流CI/CD工具对比 工具优势适用场景Jenkins插件丰富、可扩展性强复杂流水线、混合云环境GitHub Actions与GitHub深度集成、易用GitHub项目、中小团队GitLab CI/CD一体化平台、内置…...
idea json生成实体类
在IntelliJ IDEA中,可以通过安装GsonFormat或GsonFormatPlus插件快速生成Java实体类。具体操作流程包括安装插件、创建空类后使用快捷键调出生成界面,输入JSON数据即可自动生成对应字段和结构。 一、操作流程与工具选择 1、插件安装 在ID…...

C# 类和继承(抽象成员)
抽象成员 抽象成员是指设计为被覆写的函数成员。抽象成员有以下特征。 必须是一个函数成员。也就是说,字段和常量不能为抽象成员。必须用abstract修饰符标记。不能有实现代码块。抽象成员的代码用分号表示。 例如,下面取自一个类定义的代码声明了两个抽…...
gitlab rss订阅失败
问题:gitlab rss订阅失败 处理:http://gitlab.com/dashboard/projects.atom?feed_tokenXXXXXXX 这个XXX要改成用户设置里的Feed令牌 推荐本地rss订阅器:GitHub - yang991178/fluent-reader: Modern desktop RSS reader built with Electro…...

鸿蒙仓颉语言开发实战教程:商城登录页
听说Pura80要来了?感觉华为的新品像下饺子一样,让人目不暇接,每隔几天就有发布会看,真不错呀。 节后第一天,为了缓解大家假期的疲惫,咱们今天做点简单的内容,就是商城的登录页面。 其实这一次分…...

JavaScript 数组与流程控制:从基础操作到实战应用
在 JavaScript 编程的世界里,数组是一种极为重要的数据结构,它就像是一个有序的 “收纳盒”,能够将多个值整齐地存储起来。而流程控制语句则像是 “指挥官”,能够按照特定的逻辑对数组进行遍历和操作。接下来,就让我们…...
STM32中自动生成Flash地址的方法
每页大小为 2KB(0x800 字节),地址间隔为 0x800 总地址空间覆盖范围:0x08000000 ~ 0x0803F800(共 256KB) 适用于 STM32 大容量 / 中容量产品(如 F103 系列) 代码如下 // 通用定义(需根据实际页大小调整) #define FLASH_BASE_ADDR 0x08000000 #define FLASH_PAGE_SIZ…...
Matlab | MATLAB 中的插值详解
MATLAB 中的插值详解 插值是数值分析中的核心技术,用于在已知数据点之间估计未知点的值。MATLAB 提供了完整的插值函数库,涵盖一维到高维数据,支持多种插值方法。以下从基础到高级全面解析: 一、插值核心概念 1. 数学本质 给定数据点 ( x i , y i ) (x_i, y_i) (<...

SkyWalking架构深度解析:分布式系统监控的利器
一、SkyWalking概述 SkyWalking是一款开源的APM(应用性能监控)系统,专门为微服务、云原生和容器化架构设计。它由Apache软件基金会孵化并毕业,已成为分布式系统监控领域的明星项目。 核心特性 分布式追踪:跨服务调用链路的完整追踪服务…...

vue2中的render函数
<script> export default {components: {},name: "renderElems",render (h, context) {return this.$attrs.vnode;},updated() {} } </script> <style scoped> </style>分析一下上面.vue组件: 组件结构: 这是一个非…...
逆向工程开篇(连载中)
项目特点 这个专栏专门设计用于汇编逆向工程研究,包含: ✅ 18个测试模块,覆盖所有主要C语言特性✅ 1200行工具类代码,400行主程序代码✅ 完整的Visual Studio 2017项目支持✅ Debug和Release两种构建配置✅ 静态库和可执行文件分…...
this.$set() 的用法详解(Vue响应式系统相关)
1. 什么是 this.$set()? this.$set(target, key, value) 是 Vue 2 中提供的一个方法,用于向响应式对象中动态添加属性,确保新加的属性同样是响应式的。 2. 为什么需要它? Vue 2 的响应式系统基于 Object.defineProperty&#…...

PARADISE:用于新生儿缺氧缺血性脑病(HIE)疾病识别与分割的个性化和区域适应性方法|文献速递-深度学习医疗AI最新文献
Title 题目 PARADISE: Personalized and regional adaptation for HIE disease identification and segmentation PARADISE:用于新生儿缺氧缺血性脑病(HIE)疾病识别与分割的个性化和区域适应性方法 1 文献速递介绍 缺氧缺血性脑病&…...
RabbitMQ 监控与调优实战指南(二)
五、调优策略与实战:对症下药提升性能 5.1 配置参数调优 在 RabbitMQ 的性能优化中,合理调整配置参数是关键的一环,这些参数涉及内存、磁盘、网络等多个资源层面,对 RabbitMQ 的整体性能有着深远的影响。 内存相关配置…...

WordPress子主题RiPro-V5van无授权全开源版(源码下载)
WordPress子主题RiPro-V5van无授权全开源版,直接上使用方法:WordPress后台上传就行 这个主题是1.0版本开源的,有能力的可以二次开发一下加一些自己喜欢的功能。 源码下载:https://download.csdn.net/download/m0_66047725/90952148 更多资…...
保姆级Elasticsearch集群部署指导
一、环境准备 1. 硬件要求(单节点建议) CPU:至少2核(生产环境4核)内存:至少4GB(生产环境建议16GB,且为偶数,如8GB、16GB)磁盘:至少50GB SSD&…...
PyQt实现3维数组与界面TableWidget双向绑定
以下是一个使用PyQt实现3维数组与界面TableWidget双向绑定的示例代码。该程序包含一个下拉菜单选择第0维索引,表格展示第1维和第2维的数据,并支持双向数据同步: import sys import numpy as np from PyQt5.QtWidgets import (QApplication, …...

StoreView SQL,让数据分析不受地域限制
作者:章建(处知) 引言 日志服务 SLS 是云原生观测和分析平台,为 Log、Metric、Trace 等数据提供大规模、低成本、实时的平台化服务。SLS 提供了多地域支持【1】,方便用户可以根据数据源就近接入 SLS 服务,…...
护网面试题目2025
护网基础试题 一、描述外网打点的流程? 靶标确认、信息收集、漏洞探测、漏洞利用、权限获取。最终的目的是获取靶标的系统权限/关键数据。在这个过程中,信息收集最为重要。掌握靶标情报越多,后续就会有更多的攻击方式去打点。比如ÿ…...
Figma 与 Cursor 深度集成的完整解决方案
以下是 Figma 与 Cursor 深度集成的完整解决方案,实现设计-开发无缝协作: 一、集成架构设计 #mermaid-svg-NdvcKTZAZfX9DiUO {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-NdvcKTZAZfX9DiUO…...

UCRT 和 MSVC 的区别(Windows 平台上 C/C++ 开发相关)
UCRT 和 MSVC 是与 Windows 平台上 C/C 开发相关的两个重要概念,它们都属于 Microsoft 的开发工具链的一部分。下面详细解释它们的含义、区别以及用途。 一、UCRT(Universal C Runtime) 1. 含义: UCRT(Universal C …...

rabbitmq Fanout交换机简介
给每个服务创建一个队列,然后每个业务订阅一个队列,进行消费。 如订单服务起个多个服务,代码是一样的,消费的也是同一个队列。加快了队列中的消息的消费速度。 可以看到两个消费者已经在消费了...
【机器学习】集成学习与梯度提升决策树
目录 一、引言 二、自举聚合与随机森林 三、集成学习器 四、提升算法 五、Python代码实现集成学习与梯度提升决策树的实验 六、总结 一、引言 在机器学习的广阔领域中,集成学习(Ensemble Learning)犹如一座闪耀的明星,它通过组合多个基本学习器的力量,创造出…...
Palo Alto Networks Expedition存在命令注入漏洞(CVE-2025-0107)
免责声明 本文档所述漏洞详情及复现方法仅限用于合法授权的安全研究和学术教育用途。任何个人或组织不得利用本文内容从事未经许可的渗透测试、网络攻击或其他违法行为。使用者应确保其行为符合相关法律法规,并取得目标系统的明确授权。 对于因不当使用本文信息而造成的任何直…...
WebFuture:Ubuntu 系统上在线安装.NET Core 8 的步骤
方法一:使用官方二进制包安装 下载.NET Core 8 SDK 二进制包:访问 .NET Core 8 SDK 官方下载页面,根据你的系统架构选择对应的 Linux x64 版本等下载链接,将其下载到本地4. 创建安装目录:在终端中执行以下命令创建用于…...

JAVA-springboot JUnit单元测试
SpringBoot从入门到精通-第9章 JUnit单元测试 一、JUnit与单元测试 JUnit是一个开源的测试框架,虽然可以用于测试大多数编程语言的应用程序,但特别适合用于测试Java语言的应用程序。 软件测试一般分为4个阶段,即单元测试、集成测试、系统测…...
hot100 -- 6.矩阵系列
1.矩阵置零 问题:给定一个 m x n 的矩阵,如果一个元素为 0 ,则将其所在行和列的所有元素都设为 0 。请使用 原地 算法。 方法:记录行列 置0 # 记录行列,分别置0 def set_zero(matrix):row, col [], []# 统计0元素…...