这年头谁还手写逻辑删除?一个注解@TableLogic秒搞定!💘

2,551 阅读9分钟

🏆本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升持续更新中,up!up!up!!

📜 前言

  哈咯,家人们,大家好呀!作为一个追求精致代码和数据库优化的程序员,你是否也对表中的数据删除感到疑惑呢?👀传统的物理删除真的好吗?其实,有些数据只要逻辑删除掉就好,不需要直接从数据库清除。今天,就让我带你一起深入探讨MyBatisPlus中@TableLogic的实践使用,让我们在不知不觉中掌握这个关键小技能吧!💪

📚 目录

  1. 🚀 什么是逻辑删除?
  2. 🎩 MyBatisPlus 中的 @TableLogic 注解
  3. ✍️ 实战演示:使用@TableLogic进行逻辑删除
  4. 🔍 案例扩展:逻辑删除与物理删除的优劣对比
  5. 📑 复杂场景中的逻辑删除应用
  6. 🤔 逻辑删除与软删除的区别
  7. 🛠️ 逻辑删除的性能优化
  8. 📝 使用@TableLogic的注意事项
  9. 💡 实用小贴士与最佳实践
  10. 📈 总结

🚀 什么是逻辑删除?

  逻辑删除,顾名思义,就是不真的删除数据,只是“打个标记”,让它对用户不可见。就像工作中的“隐退”,只是暂时消失但依然存在。👍

  在实际开发中,我们往往不想真的删掉一条数据,而是让它在数据库里“假装”被删除。比如删除用户记录,不直接把用户删掉,而是把状态变成“已删除”,这样可以方便恢复数据和进行数据分析。😄

🎩 MyBatisPlus中的@TableLogic注解

  MyBatisPlus是一款优秀的ORM框架,它让开发者的CRUD操作变得更加方便。而在逻辑删除这一块,它提供了@TableLogic注解,只需在字段上加上这个注解,就能将删除操作变成“打标记”。✨

  在MyBatisPlus中,我们可以在实体类的字段上添加@TableLogic注解,这样在调用删除操作时就会触发逻辑删除,而不会真正将数据从数据库删除。

例如:

@TableLogic
private Integer deleted;

注意:默认情况下,deleted字段的值为0代表“未删除”,1代表“已删除”。

  当然,你可以在配置中自定义这些值,比如设置deleted=0代表“正常”,deleted=1代表“删除”。这种方式灵活又强大,特别适合需要数据持久保存的场景💡。

✍️ 实战演示:使用@TableLogic进行逻辑删除

Step 1: 创建数据库表

CREATE TABLE `user` (
  `id` bigint(32) NOT NULL AUTO_INCREMENT COMMENT 'UUID',
  `del_flag` char(1) DEFAULT '0' COMMENT '逻辑删除标记(0-正常, 1-已删除)',
  `create_by` varchar(20) NOT NULL COMMENT '创建人',
  `create_time` datetime NOT NULL COMMENT '创建时间',
  `update_by` varchar(20) NOT NULL COMMENT '更新人',
  `update_time` datetime NOT NULL COMMENT '更新时间',
  `name` varchar(128) NOT NULL COMMENT '姓名',
  `age` int(4) DEFAULT NULL COMMENT '年龄',
  `email` varchar(128) DEFAULT NULL COMMENT '邮箱',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

Step 2: 编写实体类

/**
 * user对象 user
 *
 * @author bug菌
 * @date 2024-12-02
 */
@Data
@EqualsAndHashCode(callSuper = true)
@ApiModel("user对象")
@TableName(value = "user")
public class User extends BaseEntity {
    private static final long serialVersionUID = 1L;

    /**
     * UUID
     */
    @TableId
    private Long id;

    /**
     * 逻辑删除标记(0-正常, 2-已删除)
     */
    @ApiModelProperty(value = "逻辑删除标记(0-正常, 2-已删除)")
    @Excel(name = "逻辑删除标记", readConverterExp = "0=-正常,2=-已删除")
    @TableLogic
    private String delFlag = "0";

    /**
     * 姓名
     */
    @ApiModelProperty(value = "姓名", required = true)
    @NotBlank(message = "姓名不能为空")
    @Excel(name = "姓名")
    @Size(max = 30, message = "姓名长度不能超过30")
    private String name;

    /**
     * 年龄
     */
    @ApiModelProperty(value = "年龄")
    @Excel(name = "年龄")
    private Integer age;

    /**
     * 邮箱
     */
    @ApiModelProperty(value = "邮箱")
    @Excel(name = "邮箱")
    @Size(max = 50, message = "邮箱长度不能超过50")
    private String email;
}

  如上大家可具体关注这个字段 delFlag ,对其加了@TableLogic 注解即可实现逻辑删除。

Step 3: 配置MyBatisPlus

确保逻辑删除配置正确:

mybatis-plus:
  global-config:
    db-config:
      logic-delete-field: deleted
      logic-not-delete-value: 0
      logic-delete-value: 2

Step 4: 测试逻辑删除

    /**
     * 删除user
     */
    @ApiOperation("根据用户ids删除user")
    @DeleteMapping("/{ids}")
    public R<Void> remove(@PathVariable Long[] ids) {
        return toR(userService.deleteByIds(ids));
    }

删除用户接口

    /**
     * 批量删除user
     *
     * @param ids 需要删除的user主键集合
     * @return 结果
     */
    public boolean deleteByIds(Long[] ids);

删除接口实现类:

    @Override
    public boolean deleteByIds(Long[] ids) {
        return testUserMapper.deleteBatchIds(Arrays.asList(ids)) > 0;
    }

Step 5: 本地实际测试

  这里我们采用Postman模拟测试一波,先进行新增几条数据,完了之后进行删除。

查验下数据库,进入的数据。

接着我们将其ID进行入参删除。通过Postman进行调用接口,可以看到接口调用成功。

接着我们查验下数据库其逻辑删除字段,可以看到,自动将其改成了2。

替大家又测试了一波,大家可放心食用。

🔍 案例扩展:逻辑删除与物理删除的优劣对比

特点逻辑删除物理删除
删除效果数据表保留数据,但标记为已删除彻底删除数据行
恢复可能✅ 可以简单恢复(修改标记即可)❌ 无法恢复
磁盘空间❌ 持续占用数据库空间✅ 释放空间
性能对性能影响较小对大数据表可能更有利
数据分析✅ 可用于追踪数据变化历史❌ 数据丢失,无法追溯

  综上所述,逻辑删除在业务数据安全、恢复、追踪数据等方面具有显著优势,而物理删除则在节约空间和提升性能上更胜一筹。建议视业务需求灵活选择!💡

📑 复杂场景中的逻辑删除应用

  在一些复杂的业务场景中,逻辑删除还可以进行多种应用。例如:

1. 级联逻辑删除

  假设有一个“用户”和“订单”两张表,当删除用户时可能会希望该用户的订单也被逻辑删除。这时可以在逻辑删除的同时设置级联逻辑删除的规则,实现类似“假删除”的功能。

2. 多状态字段

  有时,我们希望在删除时不仅将deleted字段置为1,还可能需要记录其他状态(如“已归档”)。这种场景下可以通过复合状态字段来实现不同的逻辑标记。

3. 软删除

  如果项目中存在多重逻辑标记需求(例如“已归档”、“已失效”、“已删除”等),可以扩展逻辑删除字段,使其支持多状态逻辑。比如:

@TableLogic(value = "0", delval = "2") // 0代表正常,1代表已归档,2代表已删除
private Integer status;

🤔 逻辑删除与软删除的区别

  虽然逻辑删除和软删除有时被视为同一概念,但实际应用中存在一些差异:

  1. 逻辑删除通常只涉及“未删除”和“已删除”两种状态,通过标记数据状态而不实际清除。

  2. 软删除通常应用在需要“归档”或“暂存”状态的数据,方便追踪更多历史变化。比如,用“软删除”标记失效而不是完全删除。

🛠️ 逻辑删除的性能优化

  逻辑删除虽然安全性强,但仍然可能对数据库性能有一定影响,尤其是在数据量较大时,以下是一些优化建议:

  1. 建立索引:在逻辑删除字段上建立索引,能够加快查询速度。例如在deleted字段上添加索引可以优化查询效率。

  2. 分区表:可以使用分区表,把已删除数据和未删除数据分开存储,进一步提升查询效率。

  3. 异步清理:对于已删除数据可以使用定期异步清理机制,定期将数据物理删除,避免数据膨胀。

  4. 合理查询逻辑:在查询中确保查询条件合理使用逻辑删除字段,以减少无关数据的读取。

📝 使用@TableLogic的注意事项

  1. 字段类型deleted字段的类型通常设为int,并确保其默认值为0。尽量不要用boolean类型,因为在某些数据库中可能不支持boolean

  2. 配置一致性:确保全局配置的逻辑删除值与注解配置保持一致。使用@TableLogic(value = "0", delval = "1")时,确保配置文件中也保持一致。

  3. 批量删除处理:批量逻辑删除时可以考虑事务控制,避免批量操作时出现错误导致部分数据未被删除。

  4. 与外键关联:逻辑删除的表尽量避免使用外键关联,否则会增加删除操作的复杂性。

💡 实用小贴士与最佳实践

  1. 使用索引:逻辑删除的表一般会设置较多字段,合理使用索引提高查询性能。

  2. 定期清理:对于不需要的数据,可定期物理删除,避免表空间持续膨胀。

  3. 日志记录:逻辑删除虽然数据还在,但也建议记录操作日志,方便数据追溯。

  4. 事务管理:逻辑删除也要注意事务管理,避免出现数据不一致的问题。

📈 总结

  总的来说,MyBatisPlus的逻辑删除功能提供了更安全的数据管理方式。在一些数据安全性高的业务场景中,逻辑删除会是更好的选择。学会了@TableLogic注解的用法后,大家可以更加轻松地实现数据逻辑删除,而不再依赖复杂的自定义标记代码🚀,助你解放双手。

  在使用过程中,逻辑删除的优点是明显的,尤其是在用户记录和日志管理等方面。但是,逻辑删除也会增加数据库负担,因此需要结合实际需求进行选择😊。

📣 关于我

我是bug菌,CSDN | 掘金 | InfoQ | 51CTO | 华为云 | 阿里云 | 腾讯云 等社区博客专家,C站博客之星Top30,华为云2023年度十佳博主,掘金多年度人气作者Top40,掘金等各大社区平台签约作者,51CTO年度博主Top12,掘金/InfoQ/51CTO等社区优质创作者;全网粉丝合计 30w+;硬核微信公众号「猿圈奇妙屋」,欢迎你的加入!免费白嫖最新BAT互联网公司面试真题、4000G PDF电子书籍、简历模板等海量资料,你想要的我都有,关键是你不来拿哇。

-End-