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

别再踩坑了!MybatisPlus更新字段为null的三种正确姿势(附UpdateWrapper实战)

MyBatis-Plus字段更新策略深度解析三种方式精准控制NULL值写入引言在日常开发中数据更新是最基础也最频繁的操作之一。但许多开发者在使用MyBatis-Plus进行字段更新时经常会遇到一个看似简单却令人困惑的问题为什么通过set方法将字段设置为null后数据库中的值并没有如预期那样被更新为NULL这背后其实隐藏着MyBatis-Plus的字段更新策略机制。本文将深入剖析这一问题的根源并给出三种实用解决方案帮助开发者根据实际业务场景选择最合适的处理方式。理解MyBatis-Plus的字段更新策略对于编写健壮、可维护的数据访问层代码至关重要。无论是用户信息管理中的清空邮箱操作还是订单系统中的备注重置功能都需要开发者对字段更新有精准控制。通过本文你将掌握全局配置、字段注解和UpdateWrapper三种方法的适用场景、实现细节和性能考量避免在未来的开发中重复踩坑。1. MyBatis-Plus字段更新策略原理解析1.1 FieldStrategy的四种策略MyBatis-Plus通过FieldStrategy枚举类定义了字段的更新策略这是控制NULL值能否成功写入数据库的核心机制。理解这四种策略的差异是解决问题的第一步public enum FieldStrategy { IGNORED, // 0.3.x版本已过时等同于ALWAYS NOT_NULL, // 非NULL判断默认策略 NOT_EMPTY, // 非空判断包含NULL和空字符串 NEVER; // 永远不更新该字段 }在3.x版本中FieldStrategy被细化为更明确的策略public enum FieldStrategy { ALWAYS, // 总是更新无论字段值是否为null NOT_NULL, // 非NULL判断默认 NOT_EMPTY, // 非空判断 DEFAULT, // 跟随全局配置 NEVER; // 永远不更新 }策略对比表策略类型3.0.x版本3.1.2版本处理NULL值处理空字符串适用场景忽略判断IGNOREDALWAYS更新为NULL更新为空字符串强制更新场景非NULL判断NOT_NULLNOT_NULL忽略更新更新为空字符串默认配置防止误清空非空判断NOT_EMPTYNOT_EMPTY忽略更新忽略更新严格校验场景永不更新NEVERNEVER忽略更新忽略更新只读字段1.2 默认策略导致的问题分析MyBatis-Plus默认采用NOT_NULL策略这是许多开发者遇到设置null无效问题的根本原因。当执行如下代码时User user new User(); user.setId(1L); user.setEmail(null); // 尝试清空邮箱 userMapper.updateById(user);生成的SQL语句中不会包含email字段的更新因为NOT_NULL策略会主动忽略值为null的字段。这种设计本意是防止开发者在不知情的情况下意外清空字段但在需要明确设置NULL值的业务场景中就会造成困扰。2. 全局配置方案一劳永逸的解决方式2.1 配置方法与参数说明全局配置是最彻底的解决方案适用于项目中需要频繁处理NULL值更新的场景。在application.yml中配置如下mybatis-plus: global-config: db-config: field-strategy: ALWAYS # 全局字段策略设置为ALWAYS或者在application.properties中mybatis-plus.global-config.db-config.field-strategyALWAYS注意全局修改会影响所有实体类的所有字段务必评估项目整体需求后再决定是否采用此方案。2.2 优缺点分析与适用场景优势配置简单一次修改全局生效不需要在每个字段上单独添加注解适合新项目或需要大量NULL值处理的系统缺点缺乏灵活性所有字段都会受到影响可能意外更新不需要设置为NULL的字段不利于代码的局部控制和明确意图表达典型应用场景数据清洗和迁移工具需要频繁清空字段的业务系统项目初期确定需要大量NULL值处理的场景3. 字段注解方案精准控制的推荐做法3.1 TableField注解详解对于大多数项目字段级别的控制是更推荐的做法。MyBatis-Plus提供了TableField注解来细粒度控制单个字段的策略public class User { TableField(updateStrategy FieldStrategy.ALWAYS) private String email; TableField(updateStrategy FieldStrategy.NOT_NULL) private String username; }3.1.2版本支持更精细的控制TableField(insertStrategy FieldStrategy.NOT_EMPTY, updateStrategy FieldStrategy.ALWAYS, whereStrategy FieldStrategy.NOT_EMPTY) private String mobile;3.2 多策略组合实战不同业务字段可以采用不同的策略组合public class Order { TableField(updateStrategy FieldStrategy.NEVER) private Long id; // 主键永不更新 TableField(updateStrategy FieldStrategy.ALWAYS) private String remark; // 备注允许清空 TableField(updateStrategy FieldStrategy.NOT_EMPTY) private String productCode; // 产品编码不能为空 TableField(updateStrategy FieldStrategy.NOT_NULL) private BigDecimal amount; // 金额可为0但不能为null }3.3 版本兼容性注意事项3.0.x版本使用数值表示策略TableField(strategy FieldStrategy.IGNORED) // 等效于ALWAYS3.1.0版本建议使用新枚举值4.x版本保持与3.1.2相同的API4. UpdateWrapper方案灵活的动态更新4.1 LambdaUpdateWrapper基础用法对于需要动态决定是否更新为NULL的场景UpdateWrapper提供了最大的灵活性LambdaUpdateWrapperUser wrapper Wrappers.lambdaUpdate(User.class) .eq(User::getId, 1L) .set(User::getName, 新名称) .set(User::getEmail, null); // 明确设置NULL userMapper.update(null, wrapper);生成的SQL会明确包含emailNULL的条件。4.2 复杂更新场景示例组合多种更新操作public void updateUserProfile(Long userId, UserProfileVO vo) { LambdaUpdateWrapperUser wrapper Wrappers.lambdaUpdate(User.class) .eq(User::getId, userId); if (vo.getAvatar() ! null) { wrapper.set(User::getAvatar, vo.getAvatar()); } if (vo.getClearEmail()) { wrapper.set(User::getEmail, null); // 根据条件清空邮箱 } else if (vo.getEmail() ! null) { wrapper.set(User::getEmail, vo.getEmail()); } userMapper.update(null, wrapper); }4.3 性能优化建议批量更新时复用Wrapper对象避免在循环中创建新Wrapper复杂条件优先使用Lambda表达式保证类型安全5. 三种方案的综合对比与选型指南5.1 功能对比矩阵对比维度全局配置字段注解UpdateWrapper配置复杂度低一次配置中按字段配置高每次动态构建灵活性低中高代码侵入性无需要修改实体类无NULL处理明确性隐式显式显式适合场景统一策略的新项目需要细粒度控制动态条件更新5.2 实际项目中的选择建议新项目初期可以先采用全局ALWAYS策略后期根据需要逐步添加字段注解存量项目改造优先使用字段注解修改关键字段配合UpdateWrapper处理特殊场景复杂业务系统组合使用字段注解和UpdateWrapper保持灵活性和明确性性能敏感场景避免频繁创建UpdateWrapper考虑缓存或批量处理5.3 常见陷阱与最佳实践陷阱1混用实体类set和Wrapper导致冲突// 错误示例实体类设置了非null值会覆盖Wrapper的null设置 userMapper.update(new User().setName(不会生效), Wrappers.lambdaUpdate(User.class) .set(User::getName, null));陷阱2全局配置与字段注解冲突时字段注解优先级更高最佳实践保持策略的一致性同一字段不要在不同地方采用不同策略在领域模型中通过方法明确操作意图public class User { public void clearEmail() { this.email null; } }对关键字段添加注释说明更新策略选择原因6. 深入原理MyBatis-Plus的SQL生成机制6.1 策略判断流程解析MyBatis-Plus在生成UPDATE语句时会经过以下判断流程检查字段是否有TableField注解及updateStrategy设置若无注解使用全局配置的策略根据策略判断是否应该包含该字段在SQL中对于Wrapper方式直接包含所有明确set的字段6.2 自定义策略扩展高级场景下可以实现自定义策略public class CustomFieldStrategy implements IFieldStrategy { Override public boolean skip(TableFieldInfo tableFieldInfo, Object value) { // 自定义跳过逻辑 } }然后在配置中指定mybatis-plus: global-config: db-config: field-strategy: com.your.package.CustomFieldStrategy6.3 与MyBatis原生机制的协作MyBatis-Plus的字段策略最终会转换为MyBatis的SQL节点// 简化后的逻辑示例 if (fieldStrategy.skip(fieldInfo, value)) { sqlSourceBuilder.skipField(fieldInfo.getColumn()); } else { sqlSourceBuilder.appendField(fieldInfo.getColumn(), value); }理解这一层关系有助于调试复杂的更新场景。

相关文章:

别再踩坑了!MybatisPlus更新字段为null的三种正确姿势(附UpdateWrapper实战)

MyBatis-Plus字段更新策略深度解析:三种方式精准控制NULL值写入 引言 在日常开发中,数据更新是最基础也最频繁的操作之一。但许多开发者在使用MyBatis-Plus进行字段更新时,经常会遇到一个看似简单却令人困惑的问题:为什么通过set方…...

CarPlay无线连接背后的‘握手’秘密:深入解读iAP2协议与蓝牙/Wi-Fi协同

CarPlay无线连接背后的‘握手’秘密:深入解读iAP2协议与蓝牙/Wi-Fi协同 当我们将iPhone靠近支持CarPlay的车载系统时,那个看似简单的无线连接背后,实际上隐藏着一场精密的数字芭蕾。这不是简单的蓝牙配对,而是一套由苹果精心设计的…...

3个步骤轻松将VR视频转为普通设备可播放的2D格式:VR-Reversal实用指南

3个步骤轻松将VR视频转为普通设备可播放的2D格式:VR-Reversal实用指南 【免费下载链接】VR-reversal VR-Reversal - Player for conversion of 3D video to 2D with optional saving of head tracking data and rendering out of 2D copies. 项目地址: https://gi…...

RabbitMQ系列文章(第二篇):RabbitMQ环境搭建——Windows/Linux/docker全教程(避坑指南)

大家好,欢迎来到RabbitMQ系列的第二篇文章!上一篇我们搞懂了消息队列的核心价值、主流MQ的对比,以及RabbitMQ的优势,今天我们正式进入实操环节——环境搭建。 环境搭建是所有实操的基础,也是新手最容易踩坑的环节&…...

避坑指南:Qt中实现双滑块的4种方法全解析(自绘、继承、样式表与事件过滤)

Qt双滑块控件实现方案深度评测与技术选型指南 在音视频编辑、数据可视化等专业软件领域,双滑块控件已成为时间轴选取、色彩范围调节等功能的标配交互元素。作为Qt开发者,面对"如何高效实现双滑块"这个看似简单的需求时,往往会陷入技…...

专业术语统计报告_面向复杂多场景下综合能源系统供需平衡的综合需求响应策略研究

专业术语统计报告_面向复杂多场景下综合能源系统供需平衡的综合需求响应策略研究 一、概要简析 【概要分析】 本文档《面向复杂多场景下综合能源系统供需平衡的综合需求响应策略研究》超用心地围绕研究主题展开了系统性探讨哦😜!文档总字符数足足有16543…...

别再乱用$了!Godot GDScript中$符号的5个高效用法与3个常见报错解决

别再乱用$了!Godot GDScript中$符号的5个高效用法与3个常见报错解决 在Godot引擎的日常开发中,GDScript的$符号就像一把双刃剑——用得好能大幅提升开发效率,用得不好则会让代码充满隐患。许多从Unity转战Godot的开发者,往往带着&…...

文档站点生成器 - Sphinx

简介 Sphinx 是一个高度可扩展、功能丰富的文档生成工具,最初为 Python 官方文档开发,现已成为技术文档领域的事实标准。它支持从 reStructuredText 或 Markdown 源文件生成多种输出格式(HTML、PDF、ePub、LaTeX 等)。 核心特点 …...

多模态视频理解与GRPO强化学习技术解析

1. 多模态视频理解的技术背景与挑战视频理解作为计算机视觉领域的重要研究方向,已经从早期的单一模态分析发展到如今的跨模态融合阶段。传统视频分析方法主要依赖视觉特征提取,如使用3D卷积神经网络处理时序信息,或通过双流网络分别建模空间和…...

商城产品详情页的客服咨询在哪里设置详解:从入门到实战全攻略

关于这个问题,很多商家都不太清楚。今天来详细解答。一、问题背景在实际运营小程序商城的过程中,不少商家会遇到:商城产品详情页的客服咨询在哪里设置二、详细解答通过产品详情页内设置客服功能,具体请参考以下教程:1.…...

python-103-操作的技巧和注意事项(一)shell粘贴命令行参数及subprocess执行系统命令及字典传参

文章目录 1 shell粘贴命令行参数 1.1 问题描述 1.2 支持的字符串长度 1.3 复制粘贴参数 1.4 解决方案 2 subprocess 2.1 参数含义 2.2 安全提示 2.3 安全路径 3 字典作为函数参数 3.1 原始字典会变化 3.2 若不想改变原始字典 4 字典传参 4.1 函数调用时(使用**解包字典) 4.2 函…...

3分钟快速掌握微信聊天记录解密:WechatDecrypt工具终极指南

3分钟快速掌握微信聊天记录解密:WechatDecrypt工具终极指南 【免费下载链接】WechatDecrypt 微信消息解密工具 项目地址: https://gitcode.com/gh_mirrors/we/WechatDecrypt 你是否曾经因为误删了重要的微信聊天记录而感到焦虑?或者需要找回某次关…...

鸣潮游戏自动化终极指南:基于图像识别的智能辅助解决方案

鸣潮游戏自动化终极指南:基于图像识别的智能辅助解决方案 【免费下载链接】ok-wuthering-waves 鸣潮 后台自动战斗 自动刷声骸 一键日常 Automation for Wuthering Waves 项目地址: https://gitcode.com/GitHub_Trending/ok/ok-wuthering-waves 你是否厌倦了…...

【HALCON 实战入门】15. Blob分析

欢迎订阅【HALCON 实战入门】专栏: 1. HALCON 简介与安装 5. 相机接入与图像采集 10. 阈值分割与目标提取 11. 区域处理与分析 12. 边缘检测与轮廓提取 13. 轮廓分析与几何特征 14. 形态学处理 15. Blob分析 16. 图像匹配 【HALCON 实战入门】15. Blob分析一、什么是…...

Autovisor:2025年智慧树课程自动化学习终极解决方案

Autovisor:2025年智慧树课程自动化学习终极解决方案 【免费下载链接】Autovisor 2025智慧树刷课脚本 基于Python Playwright的自动化程序 [有免安装版] 项目地址: https://gitcode.com/gh_mirrors/au/Autovisor Autovisor是一款基于Python Playwright框架开发…...

图书管理系统核心功能覆盖图书全生命周期管理,包括购入、借阅、归还、注销四大业务流程,同时支持读者信息

本节内容来自《软件设计师教程(第5版)》第12章相关章节,为图书管理系统的结构化分析阶段成果: 12.1.1 需求说明 图书管理系统核心功能覆盖图书全生命周期管理,包括购入、借阅、归还、注销四大业务流程,同时…...

软件设计师考试聚焦软件设计开发的主流技术与工程实践,要求应试者不仅掌握基础理论知识

软件设计师考试聚焦软件设计开发的主流技术与工程实践,要求应试者不仅掌握基础理论知识,更能将设计方法与原则应用到实际系统的分析、设计和开发环节。其核心技术领域可归纳为五大模块: 结构化分析与设计 数据库分析与设计 面向对象分析与设计…...

从问卷设计到论文发表:一份完整的验证性因子分析(CFA)保姆级避坑指南

从问卷设计到论文发表:一份完整的验证性因子分析(CFA)保姆级避坑指南 当你第一次接触验证性因子分析(CFA)时,可能会被各种专业术语和统计指标搞得晕头转向。作为一名经历过无数次CFA分析的研究者&#xff0…...

【仅限首批认证开发者】MCP 2026边缘性能调优密钥包:含3个未公开eBPF观测脚本+12个YAML黄金模板

更多请点击: https://intelliparadigm.com 第一章:MCP 2026边缘部署性能优化概览 MCP 2026(Model Control Protocol v2026)是面向边缘智能设备的新一代轻量化协议栈,其核心设计目标是在资源受限的ARM64/RT-Thread/RIS…...

保姆级教程:Hyper-V虚拟机通过内部网络共享WiFi上网,并配置CentOS/Ubuntu静态IP(附MobaXterm连接)

Hyper-V虚拟机内网共享WiFi上网与Linux静态IP配置全指南 1. 环境准备与基础概念 在Windows平台上使用Hyper-V创建Linux虚拟机时,网络配置往往是新手面临的第一个挑战。不同于有线网络的直连特性,WiFi环境下的虚拟机网络共享需要更精细的配置。我们先明确…...

minimind模型训练

项目包括供完整的 MiniMind-LLM 结构代码&#xff08;Dense MoE&#xff09;&#xff0c;当前主线结构对齐 Qwen3 / Qwen3-MoE 生态。提供 Tokenizer 与分词器训练代码&#xff0c;支持 <tool_call>、<tool_response>、<think> 等模板标记。覆盖 Pretrain、…...

别再只用纯色背景了!用CSS的linear-gradient和radial-gradient给你的网站加点‘料’

用CSS渐变打造高级视觉层次&#xff1a;从基础技法到设计实战 你是否已经厌倦了千篇一律的纯色背景&#xff1f;在当今追求极致用户体验的网页设计领域&#xff0c;一个精心设计的渐变背景往往能成为吸引用户驻留的关键细节。作为前端开发者&#xff0c;我们手中的linear-gradi…...

ISO-Bench:AI生成代码性能评估基准测试实践

1. 项目背景与核心价值在软件开发领域&#xff0c;代码生成与优化一直是提升工程效率的关键环节。最近两年&#xff0c;AI编码助手的爆发式增长让"用自然语言描述需求&#xff0c;自动生成可运行代码"这一愿景逐渐成为现实。但一个长期被忽视的问题是&#xff1a;这些…...

从纸质到数字:用Audiveris让古老乐谱重获新生的魔法

从纸质到数字&#xff1a;用Audiveris让古老乐谱重获新生的魔法 【免费下载链接】audiveris Latest generation of Audiveris OMR engine 项目地址: https://gitcode.com/gh_mirrors/au/audiveris 你是否有一叠泛黄的乐谱&#xff0c;承载着岁月的记忆却难以传承&#x…...

为AI代码生成器Cursor配置ESLint与Prettier规则集,实现自动化代码规范检查与格式化

1. 项目概述&#xff1a;为 Cursor 编辑器注入代码规范的灵魂如果你和我一样&#xff0c;日常重度依赖 Cursor 这款 AI 驱动的编辑器来加速开发&#xff0c;那你一定体会过那种“痛并快乐着”的感觉。快乐在于&#xff0c;它确实能帮你快速生成代码片段、重构函数&#xff0c;甚…...

解锁旧Mac新生命:OpenCore Legacy Patcher完全指南

解锁旧Mac新生命&#xff1a;OpenCore Legacy Patcher完全指南 【免费下载链接】OpenCore-Legacy-Patcher Experience macOS just like before 项目地址: https://gitcode.com/GitHub_Trending/op/OpenCore-Legacy-Patcher 你是否还在为心爱的旧Mac无法升级最新macOS而烦…...

MARS算法原理与Python实现:非线性回归实战指南

1. MARS算法核心原理拆解多元自适应回归样条(Multivariate Adaptive Regression Splines)是一种非线性回归技术&#xff0c;由Jerome Friedman在1991年提出。它通过分段线性回归的方式自动构建预测模型&#xff0c;特别适合处理高维数据中的复杂非线性关系。1.1 基础数学框架MA…...

在 Ubuntu 上为 Claude Code 配置 Taotoken 作为 Anthropic 兼容后端

在 Ubuntu 上为 Claude Code 配置 Taotoken 作为 Anthropic 兼容后端 1. 准备工作 在开始配置前&#xff0c;请确保已满足以下条件&#xff1a;Ubuntu 系统已安装 Claude Code 编程助手&#xff0c;并拥有有效的 Taotoken API Key。API Key 可在 Taotoken 控制台的「API 密钥…...

php内核 自研加密算法底层嵌入PHP内核方法

最佳方式不是硬改 php-src 内核代码&#xff0c;而是写一个 PHP 扩展&#xff08;C 扩展&#xff09;把算法嵌进去。 这样升级oPHPu版本时成本最低、最稳、可回滚。---先说大白话架构你要“底层嵌入”&#xff0c;有 3 条路&#xff…...

三步搞定抖音内容保存:你的专属无水印下载神器

三步搞定抖音内容保存&#xff1a;你的专属无水印下载神器 【免费下载链接】douyin-downloader A practical Douyin downloader for both single-item and profile batch downloads, with progress display, retries, SQLite deduplication, and browser fallback support. 抖音…...