MyBatis-Plus 逻辑删除
在实际开发中,直接从数据库删除数据(物理删除)存在误操作后难以恢复的风险。MyBatis-Plus 提供的逻辑删除功能通过标记字段标识数据状态,既保留了数据完整性,又实现了“删除”效果。
一、逻辑删除核心概念
逻辑删除并非真正从数据库中删除数据,而是通过一个标记字段(如 deleted
)记录数据状态:
- 未删除:标记字段值为
0
(默认); - 已删除:标记字段值为
1
(默认)。
执行“删除”操作时,实际执行的是更新标记字段的 SQL;查询数据时,自动过滤已删除的记录。这种方式既避免了数据丢失,又不影响业务查询逻辑。
二、逻辑删除实现步骤
1. 数据库表添加标记字段
在需要支持逻辑删除的表中添加 deleted
字段(名称可自定义),类型为整数,默认值设为 0
(未删除):
-- 以 student 表为例
ALTER TABLE student ADD COLUMN deleted INT DEFAULT 0 COMMENT '逻辑删除标记(0-未删,1-已删)';
2. 实体类配置标记字段
在实体类中添加 deleted
字段,并通过 @TableLogic
注解标记为逻辑删除字段:
@Data
public class Student {@TableId(type = IdType.AUTO)private Integer id;private String name;private Integer age;private String gender;// 逻辑删除标记字段@TableLogicprivate Integer deleted;
}
@TableLogic
注解的作用是:告诉 MyBatis-Plus 该字段用于逻辑删除,自动参与 SQL 拼接。
3. 全局配置逻辑删除参数
在 application.yml
中配置逻辑删除的字段名、未删除值和已删除值(默认值可省略):
mybatis-plus:global-config:db-config:# 逻辑删除字段名(与实体类字段一致)logic-delete-field: deleted# 逻辑未删除值(默认0)logic-not-delete-value: 0# 逻辑已删除值(默认1)logic-delete-value: 1
通过全局配置,所有实体类的逻辑删除字段将统一遵循此规则。
三、逻辑删除操作案例
配置完成后,原有的 CRUD 方法会自动适配逻辑删除规则:
1. 删除操作(实际执行更新)
调用 deleteById
等删除方法时,MyBatis-Plus 会自动生成更新标记字段的 SQL:
@Test
public void testDelete() {// 调用删除方法(实际执行:UPDATE student SET deleted=1 WHERE id=1 AND deleted=0)studentMapper.deleteById(1);
}
执行后,id=1
的记录 deleted
字段变为 1
,而非从表中删除。
2. 查询操作(自动过滤已删除数据)
执行查询时,MyBatis-Plus 会自动在 SQL 中添加 deleted=0
条件,过滤已删除数据:
@Test
public void testSelect() {// 查询所有未删除数据(自动添加条件:WHERE deleted=0)List<Student> students = studentMapper.selectList(null);// 根据ID查询(自动添加条件:WHERE id=1 AND deleted=0)Student student = studentMapper.selectById(1); // 若id=1的记录已被逻辑删除,返回null
}
3. 更新操作(仅更新未删除数据)
更新操作会自动添加 deleted=0
条件,避免更新已删除的记录:
@Test
public void testUpdate() {Student student = new Student();student.setId(1);student.setName("更新测试");// 执行更新(自动添加条件:WHERE id=1 AND deleted=0)studentMapper.updateById(student);// 若记录已被逻辑删除,更新无效果
}
四、逻辑删除与物理删除的区别
操作类型 | 物理删除(默认) | 逻辑删除 |
---|---|---|
执行SQL | DELETE FROM 表 WHERE id=? | UPDATE 表 SET deleted=1 WHERE id=? AND deleted=0 |
数据状态 | 从表中永久移除 | 保留在表中,deleted 字段标记为1 |
恢复难度 | 需从备份恢复,难度大 | 直接将 deleted 改回0即可恢复 |
适用场景 | 临时数据、无备份需求 | 核心业务数据、需保留历史记录 |
五、建议
- 字段类型选择:逻辑删除字段建议使用
INT
类型,默认值0
(未删除),避免使用BIT
类型(部分数据库兼容性差)。 - 索引优化:在
deleted
字段上建立索引,提升查询时的条件过滤效率。 - 配合自动填充:结合 MyBatis-Plus 的自动填充功能,在插入数据时自动为
deleted
字段赋值0
(未删除):
然后在填充类中设置默认值:@TableField(fill = FieldFill.INSERT) @TableLogic private Integer deleted;
@Override public void insertFill(MetaObject metaObject) {this.setFieldValByName("deleted", 0, metaObject); }
总结
逻辑删除通过标记字段实现数据“假删除”,既保障了数据安全,又简化了恢复操作,是核心业务数据的最佳删除方案。MyBatis-Plus 通过 @TableLogic
注解和全局配置,自动适配 CRUD 方法的 SQL 生成,无需手动编写特殊逻辑。