当前位置: 首页 > ai >正文

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 类型处理器需要继承 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);}@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 类型处理器,如 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.xdnf.cn/news/11976.html

相关文章:

  • Linux系统-基本指令(6)
  • Python 多线程编程全面学习指南
  • 优化技巧--滑动窗口
  • AI物体识别原理综述与Auto Drive实践
  • 光学系统常用光学参数的测量
  • 武汉火影数字|互动多媒体展项打造:开启沉浸式互动体验
  • python打卡训练营打卡记录day44
  • ShardingSphere 如何解决聚合统计、分页查询和join关联问题
  • 导出onnx的两种方法
  • 高性能图片优化方案
  • 使用PyInstaller将Python脚本打包成可执行文件
  • C++抽象类与多态实战解析
  • [leetcode ] 5.29week | dp | 组合数学 | 图 | 打家劫舍
  • 68 VG的基本信息查询
  • SQL 中 JOIN 的执行顺序优化指南
  • RAMSUN分享全新超值型MM32F0050系列MCU
  • 理解继承与组合的本质:Qt 项目中的设计选择指南
  • 如何量化创新项目的成功标准
  • js鼠标事件大全
  • 滚珠导轨在光学设备中如何实现微米级运动?
  • 简单网络拓扑实验
  • 第一篇:Liunx环境下搭建PaddlePaddle 3.0基础环境(Liunx Centos8.5安装Python3.10+pip3.10)
  • 30 C 语言递归算法详解:基准条件、递归逻辑、循环对比、经典案例(斐波那契、猴子吃桃、汉诺塔、二分查找等)
  • Maskrcnn网络结构学习
  • Ubuntu更新国内源
  • Python 训练营打卡 Day 43
  • Vue前端篇——项目目录结构介绍
  • NER实践总结,记录一下自己实践遇到的各种问题。
  • 【linux】全志Tina预编译一个so库文件到根文件系统/usr/lib/下
  • 拉深工艺模块——回转体拉深件毛坯尺寸的确定(二)