MyBatis-Plus的@TableLogic更新失效陷阱

起因:

事情是这样的 —— 昨天风和日丽,本想优雅地写完一个更新接口就下班,结果这接口跟我玩起了捉迷藏:调用成功了,SQL 日志也打印了,数据库里的数据却纹丝不动!😤

一、🕵️ 排查过程:一顿操作猛如虎,结果全是二百五

  1. 首先检查 SQL 日志:完美!生成的 UPDATE 语句完全符合预期,参数也没错
  2. 接着怀疑数据库事务:查了半天,事务提交正常,没毛病
  3. 然后猜测是不是数据被逻辑删除了?查了数据库的 is_del 字段,明明是 0(未删除)啊!
  4. 最后甚至怀疑是缓存问题:清了缓存,重启服务,问题依旧...

就在我快要怀疑人生的时候,突然瞥见实体类上的一行代码:

@TableLogic
private Integer isDel;

抱着 "死马当活马医" 的心态,我注释掉了这个注解,再次调用接口 —— 奇迹发生了!数据更新成功了!🤯

二、🤔 为什么 @TableLogic 会搞事情?

这个注解的本职工作是帮我们自动处理逻辑删除:

  • 查询时自动加 WHERE is_del = 0
  • 删除时自动变成 UPDATE ... SET is_del = 1

但它有个隐藏特性:更新操作也会自动带上 is_del = 0 的条件!

也就是说,即使你的代码里没写,MyBatis-Plus 也会默默给你生成这样的 SQL:

UPDATE user SET name = '张三' WHERE id = 1 AND is_del = 0

那为什么我的数据 is_del 明明是 0 却更新失败?后来发现是因为我在全局配置里给逻辑删除字段设了默认值,而这个默认值和实体类注解的配置产生了隐秘的冲突... 具体为啥至今没完全搞懂,反正就是抽风了!😅

三、🚧 填坑指南:如何优雅避开这个坑?

如果你也遇到类似问题,这里有几个解决方案:

1、临时方案:直接去掉 @TableLogic 注解

手动在查询条件里加 eq("isDel", 0),虽然麻烦但踏实

2、正确姿势:使用 UpdateWrapper 明确指定条件

UpdateWrapper<User> wrapper = new UpdateWrapper<>();
wrapper.eq("id", userId)
       .set("name", newName)
       // 明确指定逻辑删除条件,覆盖自动生成的条件
       .eq("is_del", 0);
userMapper.update(null, wrapper);

3、终极方案:检查全局配置与注解是否匹配

# 确保全局配置和注解的字段、值都一致
mybatis-plus:
  global-config:
    db-config:
      logic-delete-field: isDel
      logic-not-delete-value: 0
      logic-delete-value: 1

四、📝 总结一下

@TableLogic 是个好东西,能帮我们省不少事,但它的自动条件拼接有时候会像个 "热心过头的邻居"—— 好心办坏事。

记住这几点能少走弯路:

  • 逻辑删除字段的配置要全局统一
  • 更新操作遇到诡异问题时,检查一下是不是它在搞鬼
  • 复杂场景下,手动控制条件比依赖自动拼接更靠谱

希望我的踩坑经历能帮你避开这个 "隐形炸弹"!如果觉得有用,就点个赞再走吧~👍

<think>嗯,用户这次想了解MyBatis-Plus的逻辑删除和逆向工程实现方法,正好之前我们讨论过快速排序,看来用户是个开发者,正在学习后端框架技术。从提问方式看,ta应该是个有明确目标的务实型学习者,可能正在搭建SpringBoot项目。 用户引用的四篇资料很有意思:引用1强调MyBatis-Plus的兼容性原则,引用2/4重点描述逆向工程,引用3提到CRUD操作。但ta真正需要的不是概念,而是具体实现逻辑。值得注意的是,用户特别标注"不是真正需求",说明ta希望跳过理论直接看实战方案。 关于逻辑删除部分,需要强调三个技术要点:字段注解配置、全局注入机制、查询自动过滤。尤其要提醒用户注意yml配置的delval-notdelval值映射关系,这个容易出错。逆向工程方面,AutoGenerator的代码模板配置是关键,用户可能更需要可视化工具推荐(如MyBatisX插件),这在引用4里提到过。 用户没有问但可能需要的隐藏知识点:1)逻辑删除索引优化问题 2)逆向工程覆盖策略。这两点在实际开发中常踩坑,考虑在回答里补充。另外ta提到"项目开发",建议给出企业级实践建议,比如测试环境才用p6spy监控SQL。 突然想到个细节:用户上次示例要求中文回答且用$...$渲染公式,但数据库领域基本用不到数学表达式。不过安全起见,还是检查下回答里有没有需要Latex的地方——确实没有,全是代码和配置项。保持示例里的引用格式就好,在yml配置块后加个[^3]引用标记。 </think>在SpringBoot项目中使用MyBatis-Plus实现逻辑删除和逆向工程的完整方案如下: --- ### 一、逻辑删除实现 **核心原理**:通过注解标记删除字段,MyBatis-Plus自动将`delete`操作转为`update`,并添加`WHERE deleted=0`条件过滤已删除数据。 #### 步骤: 1. **数据库添加删除标志字段** ```sql ALTER TABLE user ADD COLUMN deleted TINYINT(1) DEFAULT 0 COMMENT '删除标志(0:未删,1:已删)'; ``` 2. **实体类添加注解** ```java @Data public class User { @TableId private Long id; private String name; @TableLogic // 逻辑删除注解 private Integer deleted; // 推荐使用Integer而非boolean(兼容数据库默认值) } ``` 3. **配置全局逻辑删除规则** (`application.yml`) ```yaml mybatis-plus: global-config: db-config: logic-delete-field: deleted # 全局删除字段 logic-delete-value: 1 # 删除状态值 logic-not-delete-value: 0 # 未删除状态值 ``` 4. **使用效果** - **删除操作**:`userMapper.deleteById(1);` → 实际执行: ```sql UPDATE user SET deleted=1 WHERE id=1 AND deleted=0 ``` - **查询操作**:自动附加`WHERE deleted=0`条件 > **注意**:需手动创建数据库字段并初始化默认值[^1][^3] --- ### 二、逆向工程实现 **核心工具**:`AutoGenerator` + 代码模板配置,5分钟生成全套CRUD代码。 #### 步骤: 1. **添加Maven依赖** ```xml <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-generator</artifactId> <version>3.5.3</version> </dependency> <dependency> <groupId>org.freemarker</groupId> <artifactId>freemarker</artifactId> <!-- 使用Freemarker模板引擎 --> </dependency> ``` 2. **配置代码生成器** (示例) ```java public class CodeGenerator { public static void main(String[] args) { AutoGenerator generator = new AutoGenerator(); // 数据源配置 DataSourceConfig ds = new DataSourceConfig .Builder("jdbc:mysql://localhost:3306/test", "root", "123456") .build(); // 全局配置 GlobalConfig global = new GlobalConfig.Builder() .outputDir(System.getProperty("user.dir") + "/src/main/java") .author("Dev") .openDir(false) .build(); // 包配置 PackageConfig pk = new PackageConfig.Builder() .parent("com.example") .moduleName("system") .entity("entity") .mapper("mapper") .build(); // 策略配置 StrategyConfig strategy = new StrategyConfig.Builder() .addInclude("user", "order") // 指定生成表 .entityBuilder() .enableLombok() // 支持Lombok .logicDeleteColumnName("deleted") // 逻辑删除字段 .controllerBuilder() .enableRestStyle() // 生成@RestController .build(); generator.dataSource(ds) .global(global) .packageInfo(pk) .strategy(strategy) .execute(); } } ``` 3. **生成文件结构** ``` src/main/java └─com.example.system ├─entity # 实体类 (含逻辑删除字段注解) ├─mapper # Mapper接口 └─controller # RESTful接口 ``` > **企业级建议**: > - 使用 **MyBatisX插件** (IDEA) 可视化生成[^4] > - 生成后需检查字段注解与业务匹配度 > - 敏感表字段手动移除生成(如密码字段)[^2][^4] --- ### 三、最佳实践 1. **逻辑删除陷阱** - 唯一索引冲突:需将`deleted`字段加入联合唯一索引 - 关联查询:手动添加`AND t.deleted=0`避免漏过滤 2. **逆向工程优化** ```java .strategyConfig( new StrategyConfig.Builder() .entityBuilder() .superClass(BaseEntity.class) // 继承公共基类 .addIgnoreColumns("version") // 跳过乐观锁字段 ``` 3. **监控SQL执行** 启用`p6spy`监测实际SQL是否符合预期[^4]: ```yaml spring: datasource: url: jdbc:p6spy:mysql://localhost:3306/test # 添加p6spy前缀 ``` --- ### 常见问题解决 1. **逻辑删除失效** → 检查`@TableLogic`注解字段类型需与yml配置一致 → 确认数据库字段默认值为`0` 2. **生成代码缺少字段** → 检查数据库字段命名规范(勿用SQL关键字如`desc`) → 配置`StrategyConfig.setColumnNaming(NamingStrategy.underline_to_camel)` > 通过整合逻辑删除与逆向工程,开发效率可提升60%以上,但需遵守 **“生成不修改,修改不生成”** 原则保障维护性[^1][^4]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qx_java_1024

祝老板生意兴隆,财源广进!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值