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

Mybatis-Plus条件构造器实战:QueryWrapper与UpdateWrapper的进阶应用与避坑指南

1. 为什么需要条件构造器在日常开发中数据库操作是绕不开的话题。记得我刚入行时每次写SQL都要手动拼接字符串不仅容易出错还经常被SQL注入漏洞困扰。后来接触到MyBatis虽然解决了安全问题但XML中写动态SQL还是不够直观。直到遇见Mybatis-Plus的条件构造器才真正体会到什么是优雅地操作数据库。QueryWrapper和UpdateWrapper这两个神器本质上是为了解决三个核心问题类型安全告别手写字段名的字符串避免拼写错误导致的运行时异常动态条件用面向对象的方式构建复杂查询条件代码更易读易维护SQL防注入自动处理参数转义从根本上杜绝SQL注入风险举个例子我们要查询年龄大于25岁且姓名包含张的用户传统方式可能要这样写String sql SELECT * FROM user WHERE age 25; if(name ! null) { sql AND name LIKE % name %; // 这里有SQL注入风险 }而使用QueryWrapper只需要QueryWrapperUser wrapper new QueryWrapper(); wrapper.gt(age, 25) .like(StringUtils.isNotBlank(name), name, name);2. QueryWrapper深度解析2.1 基础用法实战先来看个完整的示例场景电商系统中的商品搜索功能。假设我们需要实现以下查询条件价格区间筛选商品分类多选关键词模糊匹配按销量或价格排序对应的QueryWrapper实现如下public PageProduct searchProducts(ProductQuery query, PageParam page) { QueryWrapperProduct wrapper new QueryWrapper(); // 价格区间 wrapper.between(query.getMinPrice() ! null query.getMaxPrice() ! null, price, query.getMinPrice(), query.getMaxPrice()); // 分类多选 if(CollectionUtils.isNotEmpty(query.getCategoryIds())) { wrapper.in(category_id, query.getCategoryIds()); } // 关键词搜索同时匹配标题和描述 if(StringUtils.isNotBlank(query.getKeyword())) { wrapper.and(w - w.like(title, query.getKeyword()) .or() .like(description, query.getKeyword())); } // 动态排序 if(sales.equals(query.getSortBy())) { wrapper.orderByDesc(sales_count); } else { wrapper.orderByAsc(price); } return productMapper.selectPage(page, wrapper); }2.2 动态条件构建技巧实际开发中我们经常遇到参数可能为null的情况。Mybatis-Plus提供了条件方法的变体可以智能跳过空值// 传统写法需要手动判空 if(name ! null) { wrapper.eq(name, name); } // 更优雅的写法当第二个参数为null时自动跳过 wrapper.eq(StringUtils.isNotBlank(name), name, name);对于复杂的嵌套条件可以使用lambda表达式保持代码清晰wrapper.nested(qw - qw.gt(price, 100) .or() .lt(stock, 10)) .and(qw - qw.like(name, iPhone).or().like(name, iPad));生成的SQL类似于WHERE (price 100 OR stock 10) AND (name LIKE %iPhone% OR name LIKE %iPad%)2.3 多表关联查询方案虽然QueryWrapper主要针对单表操作但配合Mybatis-Plus的TableField注解也能优雅处理关联查询// 实体类中添加关联字段注解 Data public class Order { private Long id; TableField(exist false) private ListOrderItem items; } // 查询时使用apply方法拼接JOIN语句 QueryWrapperOrder wrapper new QueryWrapper(); wrapper.apply(o.user_id u.id) .inSql(u.dept_id, SELECT id FROM dept WHERE level 2);对于更复杂的多表查询建议结合XML映射文件使用保持代码可维护性。3. UpdateWrapper高级玩法3.1 条件更新实战遇到这样一个需求批量修改用户状态但只针对特定条件的用户。用UpdateWrapper可以这样实现public int batchUpdateUserStatus(ListLong ids, Integer status) { UpdateWrapperUser wrapper new UpdateWrapper(); wrapper.in(id, ids) .eq(is_deleted, 0) // 只更新未删除的用户 .set(status, status) .set(update_time, new Date()); return userMapper.update(null, wrapper); }注意这里第一个参数传null表示不更新实体对象完全由wrapper控制SET内容。生成的SQL类似于UPDATE user SET status ?, update_time ? WHERE id IN (?,?,?) AND is_deleted 03.2 字段自增/表达式更新UpdateWrapper支持更灵活的字段更新方式// 年龄1 wrapper.setSql(age age 1); // 使用函数处理字段 wrapper.setSql(name CONCAT(name, _vip)); // 条件表达式更新 wrapper.set(status ! null, status, status) .set(amount ! null, balance, balance amount);3.3 乐观锁的完美配合结合Version注解实现乐观锁时UpdateWrapper能自动处理版本号public int updateWithLock(Long id, User user) { UpdateWrapperUser wrapper new UpdateWrapper(); wrapper.eq(id, id) .eq(version, user.getVersion()) // 带上当前版本号 .set(name, user.getName()) .set(version, user.getVersion() 1); // 版本号1 int affected userMapper.update(null, wrapper); if(affected 0) { throw new OptimisticLockException(数据已被其他事务修改); } return affected; }4. 避坑指南与性能优化4.1 索引失效的常见陷阱虽然条件构造器方便但不当使用会导致索引失效// 反例对索引字段使用函数会导致索引失效 wrapper.apply(DATE(create_time) 2023-01-01); // 正解使用范围查询 wrapper.between(create_time, 2023-01-01 00:00:00, 2023-01-01 23:59:59);其他需要注意的情况避免在索引列上使用!或操作LIKE查询尽量用右模糊like prefix%组合索引要注意最左前缀原则4.2 大数据量下的分页优化当处理百万级数据时常规的LIMIT分页会越来越慢// 低效写法深度分页性能差 PageUser page new Page(10000, 10); userMapper.selectPage(page, wrapper); // 优化方案1使用last方法拼接优化提示 wrapper.last(LIMIT 10000, 10); // 优化方案2基于游标的分页记录上一页最后一条记录的ID wrapper.gt(id, lastId).orderByAsc(id).last(LIMIT 10);4.3 事务中的注意事项在Spring事务中批量操作时建议控制单次操作的数据量Transactional public void batchProcess(ListLong ids) { // 每500条执行一次避免事务过大 Lists.partition(ids, 500).forEach(batch - { UpdateWrapperUser wrapper new UpdateWrapper(); wrapper.in(id, batch) .set(processed, true); userMapper.update(null, wrapper); }); }5. 扩展应用场景5.1 动态权限过滤实现数据权限过滤的优雅方案public QueryWrapperOrder addDataPermission(QueryWrapperOrder wrapper) { User currentUser getCurrentUser(); if(!currentUser.isAdmin()) { // 普通用户只能查看自己部门的订单 wrapper.inSql(dept_id, SELECT dept_id FROM user_dept WHERE user_id currentUser.getId()); } return wrapper; }5.2 多租户SAAS应用结合Mybatis-Plus的多租户插件自动添加租户条件Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor new MybatisPlusInterceptor(); // 添加多租户拦截器 interceptor.addInnerInterceptor(new TenantLineInnerInterceptor( new TenantLineHandler() { Override public String getTenantIdColumn() { return tenant_id; } Override public Expression getTenantId() { return new LongValue(1L); // 实际从上下文中获取 } } )); return interceptor; }5.3 与Lambda表达式的结合Java8的Lambda能让代码更安全// 传统方式有字段名拼写风险 wrapper.eq(createTime, date); // Lambda方式编译期检查 wrapper.lambda().eq(User::getCreateTime, date);对于复杂条件Lambda的优势更明显wrapper.lambda() .and(qw - qw.gt(User::getScore, 90).or().eq(User::getVipLevel, 3)) .ne(User::getStatus, 0);

相关文章:

Mybatis-Plus条件构造器实战:QueryWrapper与UpdateWrapper的进阶应用与避坑指南

1. 为什么需要条件构造器? 在日常开发中,数据库操作是绕不开的话题。记得我刚入行时,每次写SQL都要手动拼接字符串,不仅容易出错,还经常被SQL注入漏洞困扰。后来接触到MyBatis,虽然解决了安全问题&#xf…...

保姆级教程:从NCBI下载序列到MEGA7构建进化树(附拟南芥SPL15基因实战)

生物信息学实战:从基因检索到进化树构建的全流程解析 在分子生物学研究中,系统进化分析是理解基因家族演化关系的重要工具。对于刚接触生物信息学的学生来说,从零开始完成一个完整的进化树分析项目往往面临诸多挑战——如何获取目标基因序列…...

游戏后台记录器开发:从低开销捕获到硬件编码的工程实践

1. 项目概述:一个为游戏玩家设计的“后台记录器”如果你是一名资深游戏玩家,或者正在从事游戏相关的开发、测试、数据分析工作,那么你很可能遇到过这样的场景:在《艾尔登法环》里被某个Boss虐了上百次,却记不清每次失败…...

PCL2启动器:离线登录功能完整指南与实战应用

PCL2启动器:离线登录功能完整指南与实战应用 【免费下载链接】PCL Minecraft 启动器 Plain Craft Launcher(PCL)。 项目地址: https://gitcode.com/gh_mirrors/pc/PCL Plain Craft Launcher 2(PCL2)作为一款功能…...

MAA助手:解放双手的明日方舟全自动游戏管理工具实战指南

MAA助手:解放双手的明日方舟全自动游戏管理工具实战指南 【免费下载链接】MaaAssistantArknights 《明日方舟》小助手,全日常一键长草!| A one-click tool for the daily tasks of Arknights, supporting all clients. 项目地址: https://g…...

ARM Cortex-A72 GICv3中断处理机制与优化实践

1. ARM Cortex-A72 GIC CPU接口架构概述在ARMv8-A架构中,通用中断控制器(GIC)作为中断管理的核心组件,其CPU接口承担着处理器核心与中断源之间的桥梁作用。Cortex-A72处理器实现了GICv3架构规范,相较于前代GICv2,主要引入了以下关…...

ColorBrewer完整指南:如何为地图和数据可视化选择完美配色方案

ColorBrewer完整指南:如何为地图和数据可视化选择完美配色方案 【免费下载链接】colorbrewer 项目地址: https://gitcode.com/gh_mirrors/co/colorbrewer ColorBrewer是一个专为地图着色和数据可视化设计的开源配色工具,基于Cynthia Brewer博士的…...

别再死记硬背了!图解STM32按键状态机:从消抖到双击识别的完整逻辑(蓝桥杯适用)

图解STM32按键状态机:从消抖到双击识别的可视化逻辑拆解 在嵌入式开发中,按键处理看似简单,实则暗藏玄机。许多初学者在实现短按、长按和双击识别时,往往陷入代码调试的泥潭——明明逻辑看起来正确,实际运行却总出现误…...

告别DLL地狱:VisualCppRedist AIO一站式解决Windows运行库依赖难题

告别DLL地狱:VisualCppRedist AIO一站式解决Windows运行库依赖难题 【免费下载链接】vcredist AIO Repack for latest Microsoft Visual C Redistributable Runtimes 项目地址: https://gitcode.com/gh_mirrors/vc/vcredist 你是否曾因"缺少msvcp140.dl…...

Cool-Request全局请求头配置终极指南:告别重复配置的API测试新体验

Cool-Request全局请求头配置终极指南:告别重复配置的API测试新体验 【免费下载链接】cool-request IDEA API、Java Method debug tools 项目地址: https://gitcode.com/gh_mirrors/co/cool-request 你是否厌倦了在每个API请求中重复配置相同的认证Token、内容…...

ArcMap栅格图像平滑滤波实战:从焦点统计到重采样的多工具对比与应用

1. 栅格图像平滑滤波基础概念与应用场景 当你拿到一张遥感影像时,可能会发现图像上存在一些"瑕疵"——比如拼接产生的条带痕迹、传感器噪声或者不自然的过渡区域。这时候就需要用到栅格图像平滑滤波技术了。简单来说,这就像给照片做"美颜…...

[GESP202512 C++ 三级] 判断题第 3 题 ← strcmp

【题目描述】 strcmp(str1, str2) 返回 0 表示 str1 大于 str2 &#xff0c;返回正数表示两者相等。&#xff08;❌️&#xff09;【题目解析】 返回 0 → 两个字符串完全相等。 返回正数 → str1 > str2。 返回负数 → str1 < str2。...

告别硬盘数据丢失焦虑!电脑专属5种恢复方法,无踩坑,速存

日常使用电脑时&#xff0c;文件误删是高频突发状况——辛苦整理的办公文档、珍藏的生活影像、重要的程序安装包&#xff0c;一旦不小心删除&#xff0c;难免让人手足无措。好在2026年&#xff0c;随着数据存储技术的迭代与恢复工具的升级&#xff0c;电脑误删文件的恢复成功率…...

Git GitLab介绍

Git 是工具&#xff0c;GitLab 是使用这个工具的“工厂”或“协作平台”。它们是完全不同层面的东西&#xff0c;但紧密相关。下面是详细的对比&#xff1a;1. Git - 版本控制系统&#xff08;核心工具&#xff09;本质&#xff1a;一个开源的分布式版本控制软件&#xff0c;由…...

GD32C103RBT6 DAC 驱动库详细解析

本文基于GD32C10x 官方固件库 V1.0.0,深度解析 DAC 外设驱动库gd32c10x_dac.c,包含驱动概述、核心函数详解、可直接运行的工程例程,适合 GD32 单片机开发入门与实战。 一、DAC 外设概述 1.1 GD32C10x DAC 基本特性 双通道 12 位数字 / 模拟转换器(DAC0、DAC1) 输出电压范…...

FanControl终极指南:让你的Windows风扇控制变得智能又安静

FanControl终极指南&#xff1a;让你的Windows风扇控制变得智能又安静 【免费下载链接】FanControl.Releases This is the release repository for Fan Control, a highly customizable fan controlling software for Windows. 项目地址: https://gitcode.com/GitHub_Trendin…...

Ryujinx模拟器:3步搞定Switch游戏在PC上流畅运行

Ryujinx模拟器&#xff1a;3步搞定Switch游戏在PC上流畅运行 【免费下载链接】Ryujinx 用 C# 编写的实验性 Nintendo Switch 模拟器 项目地址: https://gitcode.com/GitHub_Trending/ry/Ryujinx 想在电脑上体验Switch独占大作却不知从何入手&#xff1f;Ryujinx模拟器为…...

明日方舟终极自动化助手:MAA智能辅助工具完整实战指南

明日方舟终极自动化助手&#xff1a;MAA智能辅助工具完整实战指南 【免费下载链接】MaaAssistantArknights 《明日方舟》小助手&#xff0c;全日常一键长草&#xff01;| A one-click tool for the daily tasks of Arknights, supporting all clients. 项目地址: https://git…...

Deepin Boot Maker:Linux启动盘制作的智能化解决方案

Deepin Boot Maker&#xff1a;Linux启动盘制作的智能化解决方案 【免费下载链接】deepin-boot-maker 项目地址: https://gitcode.com/gh_mirrors/de/deepin-boot-maker 在Linux系统安装领域&#xff0c;传统命令行操作的门槛让许多用户望而却步。Deepin Boot Maker作为…...

MacType终极指南:彻底解决Windows字体模糊问题的免费神器

MacType终极指南&#xff1a;彻底解决Windows字体模糊问题的免费神器 【免费下载链接】mactype Better font rendering for Windows. 项目地址: https://gitcode.com/gh_mirrors/ma/mactype 你是否厌倦了Windows系统上模糊不清的字体显示&#xff1f;长期面对锯齿边缘的…...

ACK多集群配置同步:MCP Server架构、部署与实战指南

1. 项目概述&#xff1a;ACK多集群管理平台的服务端核心如果你正在或计划使用阿里云容器服务ACK来管理多个Kubernetes集群&#xff0c;并且对如何高效、统一地分发应用配置感到头疼&#xff0c;那么你很可能已经接触或正在寻找类似“ack-mcp-server”这样的解决方案。这个项目&…...

为什么你的“--style raw”输出毫无银盐颗粒感?深度解析Midjourney V6渲染管线中未公开的卤化银模拟层

更多请点击&#xff1a; https://intelliparadigm.com 第一章&#xff1a;卤化银模拟层的光学隐喻与历史语境 在数字成像技术蓬勃发展的今天&#xff0c;回溯胶片时代的物理成像机制&#xff0c;不仅具有技术考古价值&#xff0c;更构成理解当代计算摄影底层隐喻的关键支点。“…...

ChatGPT-PerfectUI:开源前端界面部署与核心功能解析

1. 项目概述&#xff1a;一个为ChatGPT打造的“完美”前端界面如果你和我一样&#xff0c;是ChatGPT的重度用户&#xff0c;每天都要和它进行大量的对话&#xff0c;那么你肯定对官方那个略显简陋的Web界面有过一些“怨念”。功能切换不够直观、对话管理略显笨拙、界面风格万年…...

百度网盘Mac版终极加速方案:免费解锁SVIP级下载体验

百度网盘Mac版终极加速方案&#xff1a;免费解锁SVIP级下载体验 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘Mac版的蜗牛下载速度而烦…...

数据结构第6章树和二叉树:课后习题全解析(选择题+填空题+综合题+算法设计题)

第6章 树和二叉树 课后习题一、单项选择题1. 一棵有 n 个结点&#xff0c;采用链式存储的二叉树中&#xff0c;共有&#xff08; A &#xff09;个指针域为空。A. n1 B. n C. n−1 D. n−2解析&#xff1a; 链式存储二叉树中&#xff0c;每个结点有 2 个指针域&#xff08;左孩…...

5分钟掌握百度网盘高速下载神器:完全免费的开源解析工具终极指南

5分钟掌握百度网盘高速下载神器&#xff1a;完全免费的开源解析工具终极指南 【免费下载链接】baidu-wangpan-parse 获取百度网盘分享文件的下载地址 项目地址: https://gitcode.com/gh_mirrors/ba/baidu-wangpan-parse 还在为百度网盘非会员下载速度只有几十KB而烦恼吗…...

终极MifareOneTool使用指南:如何零基础玩转MIFARE经典卡的Windows图形化神器

终极MifareOneTool使用指南&#xff1a;如何零基础玩转MIFARE经典卡的Windows图形化神器 【免费下载链接】MifareOneTool A GUI Mifare Classic tool on Windows&#xff08;停工/最新版v1.7.0&#xff09; 项目地址: https://gitcode.com/gh_mirrors/mi/MifareOneTool …...

【Flutter for OpenHarmony 跨平台征文】Flutter 血压数据模型设计 + WHO标准分类算法实战指南

【Flutter for OpenHarmony 跨平台征文】Flutter 血压数据模型设计 WHO标准分类算法实战指南 欢迎加入开源鸿蒙跨平台社区&#xff1a;https://openharmonycrossplatform.csdn.net&#x1f3af; 写在前面 嗨&#xff0c;大家好&#xff01;我是上海某高校大一计算机专业的学生…...

告别裸机延时!ESP32-C3/ESP32-S3用RMT外设精准驱动WS2812B灯带(Arduino/IDF双平台教程)

ESP32-C3/ESP32-S3 RMT外设驱动WS2812B灯带实战指南 当你的灯光项目从十几颗WS2812B升级到上百颗时&#xff0c;GPIO模拟驱动方式很快就会遇到瓶颈——闪烁、卡顿、颜色失真&#xff0c;这些问题的根源在于时序精度不足。ESP32系列芯片内置的RMT&#xff08;Remote Control&…...

通达信缠论插件ChanlunX:5分钟实现专业缠论分析的终极指南

通达信缠论插件ChanlunX&#xff1a;5分钟实现专业缠论分析的终极指南 【免费下载链接】ChanlunX 缠中说禅炒股缠论可视化插件 项目地址: https://gitcode.com/gh_mirrors/ch/ChanlunX 想要在通达信中实现专业的缠论分析吗&#xff1f;ChanlunX缠论插件是你的最佳选择&a…...