2026/3/1 4:02:08
网站建设
项目流程
成都设计公司网站,wordpress网易插件,软文营销实施背景,郑州建设安全管理协会网站Mybatis-Plus更新操作时的一个坑在 MyBatis-Plus开启逻辑删除 的情况下#xff0c;updateById更新逻辑删除字段时#xff0c; “看起来执行了但实际上没有更新”的问题是一种较为常见但不易察觉的问题。背景#xff1a;项目中使用mybatis-plus且已开启逻辑删除#xff1a;1…Mybatis-Plus更新操作时的一个坑在 MyBatis-Plus开启逻辑删除 的情况下updateById更新逻辑删除字段时 “看起来执行了但实际上没有更新”的问题是一种较为常见但不易察觉的问题。背景项目中使用mybatis-plus且已开启逻辑删除1 mybatis-plus:2 global-config:3 db-config:4 logic-delete-field: deleted5 logic-delete-value: 16 logic-not-delete-value: 07 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_name2 SET deleted 13 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;34 -- updateById实际生成的SQLdeleted字段被剔除5 UPDATE record SET other_field? WHERE id ? AND deleted 0;Mybatis-Plus为什么要这样设计MyBtis-Plus 遵循 语义隔离 原则操作类型 框架方法 SQL语义 设计意图业务更新 updateById() 修改业务字段 只改数据内容不改数据状态逻辑删除 deleteById() UPDATE ... SET deleted1 标记数据为已删除状态关键机制拦截器过滤LogicDeleteInterceptor 会自动移除 SET 子句中的逻辑删除字段条件追加所有查询/更新操作都会自动追加 AND deleted 0单向操作逻辑删除被视为不可逆操作删除后不应通过业务代码恢复如何正确处理使用 MyBatis-Plus 提供的 deleteById 进行逻辑删除1 // 框架会自动生成UPDATE user SET deleted1 WHERE id? AND deleted02 recordMapper.deleteById(1L);在开启逻辑删除的前提下deleteById 不会执行物理删除而是由 MyBatis-Plus 自动生成逻辑删除 SQL其语义与框架设计完全一致。用 LambdaUpdateWrapper 显式执行逻辑删除1 // 手动指定SET子句绕过字段过滤2 LambdaUpdateWrapperRecord wrapper new LambdaUpdateWrapper();3 wrapper.eq(Record::getId, 1L).set(Record::getDeleted, 1); // 强制设置deleted字段4 recordMapper.update(null, wrapper);