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

Mybatis-Plus更新操作时的一个坑

Mybatis-Plus更新操作时的一个坑

在 MyBatis-Plus开启逻辑删除 的情况下,updateById更新逻辑删除字段时, “看起来执行了但实际上没有更新”的问题是一种较为常见但不易察觉的问题。

背景:

项目中使用mybatis-plus且已开启逻辑删除:

1 mybatis-plus:

2 global-config:

3 db-config:

4 logic-delete-field: deleted

5 logic-delete-value: 1

6 logic-not-delete-value: 0

7 update-strategy: not_empty #更新策略只更新非空

在代码中获取记录并更新逻辑删除字段:

1 useRecord record = RecordMapper.selectOne(...);

2 record.setDeleted(1);

3 RecordMapper.updateById(record);

执行结果没有明显报错,也不会有异常日志,但实际没有更新逻辑删除字段。

如果没有记录执行返回值进行判断,将导致逻辑删除失败问题被隐藏,为后续业务埋雷。

原因分析:

mybatis-plus使用逻辑删除背景下,使用updateById时,如下代码段:

1 record.setDeleted(1);

2 RecordMapper.updateById(record);

执行的sql语句是:

1 UPDATE table_name

2 SET deleted = 1

3 WHERE id = ?

4 AND deleted = 0; -- ⚠️ MyBatis-Plus 自动添加的条件

这条 SQL 在语法层面是合法的,但在 MyBatis-Plus 的设计语义中,逻辑删除并不被视为一次普通的 update 操作。

MyBatis-Plus 将“删除”与“更新”在内部逻辑上进行了区分:updateById 被设计为只能作用于“未被逻辑删除的数据”,而逻辑删除本身应通过 delete 系列方法触发。

1 -- 你期望生成的SQL(框架不会生成)2 UPDATE record SET deleted = 1 WHERE id = ? AND deleted = 0;

3

4 -- updateById实际生成的SQL(deleted字段被剔除)5 UPDATE record SET other_field=? WHERE id = ? AND deleted = 0;

Mybatis-Plus为什么要这样设计:

MyBtis-Plus 遵循 "语义隔离" 原则

操作类型 框架方法 SQL语义 设计意图

业务更新 updateById() 修改业务字段 只改数据内容,不改数据状态

逻辑删除 deleteById() UPDATE ... SET deleted=1 标记数据为"已删除"状态

关键机制:

拦截器过滤:LogicDeleteInterceptor 会自动移除 SET 子句中的逻辑删除字段

条件追加:所有查询/更新操作都会自动追加 AND deleted = 0

单向操作:逻辑删除被视为不可逆操作(删除后不应通过业务代码恢复)

如何正确处理:

使用 MyBatis-Plus 提供的 deleteById 进行逻辑删除

1 // 框架会自动生成:UPDATE user SET deleted=1 WHERE id=? AND deleted=02 recordMapper.deleteById(1L);

在开启逻辑删除的前提下,deleteById 不会执行物理删除,而是由 MyBatis-Plus 自动生成逻辑删除 SQL,其语义与框架设计完全一致。

用 LambdaUpdateWrapper 显式执行逻辑删除

1 // 手动指定SET子句,绕过字段过滤

2 LambdaUpdateWrapper<Record> wrapper = new LambdaUpdateWrapper<>();

3 wrapper.eq(Record::getId, 1L).set(Record::getDeleted, 1); // 强制设置deleted字段

4 recordMapper.update(n

ull, wrapper);

http://www.jsqmd.com/news/258509/

相关文章:

  • Postman发送POST请求,模拟请求头界面的响应信息
  • Linux内核是怎么发现内存泄漏的?深入kmemleak源码,揭秘检测原理
  • Java实习模拟面试复盘:深度剖析高并发数据库设计、Redis去重与Agent系统架构(百度日常实习后端二面)
  • Java版LeetCode热题100之二叉树的中序遍历:从递归到Morris遍历的深度解析
  • 供电系统:TN系统、TT系统、IT系统
  • Jmeter分布式压测详解
  • Java版LeetCode热题100之二叉树的最大深度:从DFS到BFS的全面解析
  • 贾子智慧AI战略五五三三落地细则(2025‑2035):认知破壁、生态重构与文明适配三阶段系统部署
  • 5分钟Pytest快速入门
  • 基于贾子智慧理论体系的中国 AI 发展与竞争国家战略(2025-2035)
  • AI 时代文明跃迁的贾子智慧评估指标体系(Kucius Wisdom Assessment System for Civilization Transition, KWACTS)
  • 能源监测管理平打造工业园区“智慧能源大脑”
  • 人类社交场合
  • 心智革命——AI搜索如何重塑人类认知与知识未来
  • 污水处理DCS数据采集组态监控系统方案
  • 基于深度学习神经网络YOLOv4目标检测的口罩识别系统
  • 群雄逐鹿——AI搜索产业竞争与商业模式变革
  • 沃尔玛购物卡回收靠谱平台TOP3推荐 - 京顺回收
  • 学Simulink--基础MPPT控制场景实例:基于Simulink的双模式MPPT(快速追踪+稳态优化)仿真
  • 基于Simulink的储能参与黑启动过程控制仿真
  • 技术深潜——AI搜索的架构演进与开源生态
  • 基于深度学习神经网络的验证码识别系统
  • 2026年AI智能办公鼠标排行榜,分析鸿容智能办公鼠标公司介绍 - 工业品牌热点
  • 基于Pytorch框架的深度学习Vision Transformer神经网络蝴蝶分类识别系统源码
  • 手把手教你学 GPU KMD--1.1:UMD、KMD 与 DDK 的协作关系——从应用到硬件的完整数据流解析
  • 吃尾巴
  • centos stream9:设置系统时区
  • 基于keras框架的LeNet/AlexNet/Vgg16深度学习神经网络花卉/花朵分类识别系统源码
  • 手把手教你学Simulink--基础MPPT控制场景实例:基于Simulink的双模式MPPT(快速追踪+稳态优化)仿真
  • 除螨除螨虫哪个品牌效果好?2026十大排行榜揭晓,照着买省心又安心! - 资讯焦点