MyBatis-Plus LambdaQuery 高级用法:JSON 路径查询与条件拼接的全场景解析

news2025/6/6 22:27:26

目录

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 类型处理器需要继承 BaseTypeHandlerAbstractJsonTypeHandler 等内置类型处理器,并实现相关方法。

示例代码

以下是一个基于 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);
    }

    @Override
    protected T parse(String json) {
        try {
            return objectMapper.readValue(json, getType());
        } catch (Exception e) {
            throw new RuntimeException("Failed to parse JSON", e);
        }
    }

    @Override
    protected 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 类型处理器,如 JacksonTypeHandlerFastjsonTypeHandler,可以直接将 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

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

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

相关文章

[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项目当中支持三类配置文件&#xff1a; application.properties a…

C# 类和继承(抽象成员)

抽象成员 抽象成员是指设计为被覆写的函数成员。抽象成员有以下特征。 必须是一个函数成员。也就是说&#xff0c;字段和常量不能为抽象成员。必须用abstract修饰符标记。不能有实现代码块。抽象成员的代码用分号表示。 例如&#xff0c;下面取自一个类定义的代码声明了两个抽…

鸿蒙仓颉语言开发实战教程:商城登录页

听说Pura80要来了&#xff1f;感觉华为的新品像下饺子一样&#xff0c;让人目不暇接&#xff0c;每隔几天就有发布会看&#xff0c;真不错呀。 节后第一天&#xff0c;为了缓解大家假期的疲惫&#xff0c;咱们今天做点简单的内容&#xff0c;就是商城的登录页面。 其实这一次分…

JavaScript 数组与流程控制:从基础操作到实战应用

在 JavaScript 编程的世界里&#xff0c;数组是一种极为重要的数据结构&#xff0c;它就像是一个有序的 “收纳盒”&#xff0c;能够将多个值整齐地存储起来。而流程控制语句则像是 “指挥官”&#xff0c;能够按照特定的逻辑对数组进行遍历和操作。接下来&#xff0c;就让我们…

SkyWalking架构深度解析:分布式系统监控的利器

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

vue2中的render函数

<script> export default {components: {},name: "renderElems",render (h, context) {return this.$attrs.vnode;},updated() {} } </script> <style scoped> </style>分析一下上面.vue组件&#xff1a; 组件结构&#xff1a; 这是一个非…

PARADISE:用于新生儿缺氧缺血性脑病(HIE)疾病识别与分割的个性化和区域适应性方法|文献速递-深度学习医疗AI最新文献

Title 题目 PARADISE: Personalized and regional adaptation for HIE disease identification and segmentation PARADISE&#xff1a;用于新生儿缺氧缺血性脑病&#xff08;HIE&#xff09;疾病识别与分割的个性化和区域适应性方法 1 文献速递介绍 缺氧缺血性脑病&…

WordPress子主题RiPro-V5van无授权全开源版(源码下载)

WordPress子主题RiPro-V5van无授权全开源版&#xff0c;直接上使用方法:WordPress后台上传就行 这个主题是1.0版本开源的&#xff0c;有能力的可以二次开发一下加一些自己喜欢的功能。 源码下载&#xff1a;https://download.csdn.net/download/m0_66047725/90952148 更多资…

StoreView SQL,让数据分析不受地域限制

作者&#xff1a;章建&#xff08;处知&#xff09; 引言 日志服务 SLS 是云原生观测和分析平台&#xff0c;为 Log、Metric、Trace 等数据提供大规模、低成本、实时的平台化服务。SLS 提供了多地域支持【1】&#xff0c;方便用户可以根据数据源就近接入 SLS 服务&#xff0c…

UCRT 和 MSVC 的区别(Windows 平台上 C/C++ 开发相关)

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

rabbitmq Fanout交换机简介

给每个服务创建一个队列&#xff0c;然后每个业务订阅一个队列&#xff0c;进行消费。 如订单服务起个多个服务&#xff0c;代码是一样的&#xff0c;消费的也是同一个队列。加快了队列中的消息的消费速度。 可以看到两个消费者已经在消费了

JAVA-springboot JUnit单元测试

SpringBoot从入门到精通-第9章 JUnit单元测试 一、JUnit与单元测试 JUnit是一个开源的测试框架&#xff0c;虽然可以用于测试大多数编程语言的应用程序&#xff0c;但特别适合用于测试Java语言的应用程序。 软件测试一般分为4个阶段&#xff0c;即单元测试、集成测试、系统测…

PyCharm中运行.py脚本程序

1.最近在弄一个python脚本程序&#xff0c;记录下运行过程。 2.编写的python程序如下 # # Copyright 2017 Pixar # # Licensed under the terms set forth in the LICENSE.txt file available at # https://openusd.org/license. # # Check whether this script is being run …

[论文阅读] 人工智能+项目管理 | 当 PMBOK 遇见 AI:传统项目管理框架的破局之路

当PMBOK遇见AI&#xff1a;传统项目管理框架的“AI适配指南” 论文信息 arXiv:2506.02214 Is PMBOK Guide the Right Fit for AI? Re-evaluating Project Management in the Face of Artificial Intelligence Projects Alexey Burdakov, Max Jaihyun Ahn Subjects: Software …

Gateway 搭建

1.创建 moudle 命名为 gateway 2,pom中引入依赖 网关依赖&#xff1b;注册中心依赖等 <!-- 网关依赖--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId></d…

pytorch基本运算-导数和f-string

引言 在前序对机器学习的探究过程中&#xff0c;我们已经深刻体会到人工智能到处都有微分求导运算&#xff0c;相关文章链接包括且不限于&#xff1a; BP神经网络 逻辑回归 对于pytorch张量&#xff0c;求导运算必不可少&#xff0c;所以本次就专门来学习一下。 f-string的用…

5.RV1126-OPENCV 图形计算面积

一.图形面积、弧长计算介绍 前面我们已经把图形轮廓的检测、画框等功能讲解了一遍。这次主要结合轮廓检测的 API 去计算图形的面积&#xff0c;这些面积可以是矩形、圆形等等。图形面积计算和弧长计算常用于车辆识别、桥梁识别等重要功能&#xff0c;常用的 API 如 contourArea…

【Android基础回顾】一:Binder机制是什么?有什么用?

Android中的Binder机制是Android系统中最核心和最基础的进程间通讯机制。 1 什么是进程间通讯机制(IPC)&#xff1f; 众所周知&#xff0c;Android系统基于Linux开发&#xff0c;Linux系统里面本来就有进程间通讯机制。 1.1 Linux的IPC(Inter-Process Communication)概览 它…

LeetCode 高频 SQL 50 题(基础版) 之 【高级查询和连接】· 上

题目&#xff1a;1731. 每位经理的下属员工数量 题解&#xff1a; select employee_id,name,reports_count,average_age from Employees t1,(select reports_to,count(*) reports_count,round(avg(age)) average_agefrom Employeeswhere reports_to is not nullgroup by repor…