当前位置: 首页 > 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.cnnetsun.cn/news/669658.html

相关文章:

  • 人类社交场合
  • 贾子智慧AI战略五五三三落地细则(2025‑2035):认知破壁、生态重构与文明适配三阶段系统部署
  • 【开题答辩全过程】以 基于Java的智慧园林管理系统为例,包含答辩的问题和答案
  • OSPF实验-HCIA-rj
  • 手把手教你学 GPU KMD”相关内容的专栏简介与目录
  • 机房U位资产管理传感器续航时间揭秘:超长待机让管理更轻松
  • 自动化提示工程的演进路径
  • 在SAP中,处理日常总账、应收、应付等外币业务时,系统默认使用汇率类型 M(平均汇率)
  • springboot-java会议室租赁系统
  • springboot-java考研资料购买驿站
  • 【开题答辩全过程】以 基于java的医院床位管理系统的设计与开发 为例,包含答辩的问题和答案
  • 电影《林深见渡》在张家口宣化八佰里影业风影片场开机
  • 工业组态平台构建可视化设备监控运维管理系统
  • 基于SpringAI的在线考试系统-考试系统DDD(领域驱动设计)实现步骤详解(2)
  • 基于SpringAI的在线考试系统-DDD(领域驱动设计)核心概念及落地架构全总结(含事件驱动协同逻辑)
  • 2026必备!9个AI论文写作软件,MBA毕业论文轻松搞定!
  • 【图像加密解密】混沌系统和DNA编码运算的图像分块加密解密【含Matlab源码 14964期】
  • klist链表
  • 【HarmonyOS NEXT】如何监听软键盘的弹出和收起事件
  • 固定翼无人机俯仰姿态模糊PID控制(设计源文件+万字报告+讲解)(支持资料、图片参考_相关定制)_文章底部可以扫码
  • ‌AI驱动的测试环境配置检查清单:全面指南
  • 领导说你潜力大,却不肯提拔你,只说明一件事
  • 2026 年前端必会的 10 个现代 CSS 布局技巧
  • 泊车十年演进
  • AI之LangChain:LangChain框架解读之工具调用和Agent逻辑实现细节梳理(并探讨与MCP和A2A关系)
  • 价值链视角下的YW公司成本控制研究
  • 互联网大厂Java小白求职面试:从缓存技术到微服务框架的循序渐进提问
  • 警惕新型网络攻击:MacStealer恶意软件借虚假ChatGPT指令传播
  • shell ${} 字符串替换和默认值设置教程
  • 宏桥收购鲁丰原因解读,产业链整合与战略分析