6.18
自动填充 & 逻辑删除
一、教学目标
- 配置MyBatis-Plus自动填充处理器,实现
createTime、updateTime字段在新增/修改时自动赋值。 - 结合全局配置与实体类注解,验证逻辑删除功能的完整执行效果。
- 区分逻辑删除与物理删除,掌握逻辑删除对增删改查SQL的自动改造规则。
二、核心知识点
- MetaObjectHandler:MyBatis-Plus提供的字段自动填充处理器接口,实现该接口后,框架会在SQL执行前自动为指定字段赋值,无需业务代码手动设置时间字段。
- @TableField(fill):实体类字段注解,通过
fill属性指定字段的填充时机,常用值包括FieldFill.INSERT(仅插入时填充)、FieldFill.INSERT_UPDATE(插入和更新时均填充)。 - 逻辑删除:通过专用字段标记记录的删除状态,替代直接删除数据的物理删除;MyBatis-Plus会在执行查询、修改、删除操作时自动追加过滤条件,已标记删除的数据不会被常规操作命中,数据仍保留在数据库中可恢复。
三、操作步骤
1. 前置准备
基于课次25的项目工程继续开发,确认项目已完成MyBatis-Plus基础配置、News实体类与Mapper层搭建,工程包含config、entity、mapper等标准包结构。
2. 创建自动填充处理器
在com.weitoutiao.config包下新建MyMetaObjectHandler类,实现MetaObjectHandler接口,分别重写插入填充、更新填充方法。
package com.weitoutiao.config;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
// 交给Spring容器管理,框架自动识别该处理器
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
// 执行INSERT插入操作时自动触发
@Override
public void insertFill(MetaObject metaObject) {
// strictInsertFill:严格插入填充,参数依次为:元对象、字段名、字段类型、填充值
this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now());
this.strictInsertFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now());
}
// 执行UPDATE更新操作时自动触发
@Override
public void updateFill(MetaObject metaObject) {
this.strictUpdateFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now());
}
}
3. 实体类补充填充注解
在News实体类中,为时间字段添加@TableField注解,绑定对应的填充时机:
createTime:仅新增时赋值
updateTime:新增和修改时都赋值
// News实体类字段补充注解示例
@TableField(fill = FieldFill.INSERT)
private LocalDateTime createTime;
@TableField(fill = FieldFill.INSERT_UPDATE)
private LocalDateTime updateTime;
4. 编写逻辑删除测试类
在项目测试目录下新建NewsMapperTest测试类,注入NewsMapper,编写根据ID删除数据的测试方法。
import com.weitoutiao.mapper.NewsMapper;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class NewsMapperTest {
@Autowired
private NewsMapper newsMapper;
@Test
void testDelete() {
// 根据ID删除数据(底层为逻辑删除)
int rows = newsMapper.deleteById(1);
System.out.println("删除条数:" + rows);
// 控制台实际执行SQL:UPDATE news SET deleted=1 WHERE id=1 AND deleted=0
}
}
代码出现红色报错时,鼠标悬停错误位置,选择导入对应依赖类即可解决。
5. 运行测试与结果验证
- 测试前通过数据库管理工具查看
news表,确认id=1的数据deleted字段值为0(未删除状态); - 点击测试方法左侧的运行按钮,执行单元测试;
- 查看控制台SQL日志:实际执行的是UPDATE修改语句,而非DELETE物理删除语句;
- 刷新数据库表,id=1的数据
deleted字段变为1,代表逻辑删除标记成功; - 调用普通查询接口时,已标记删除的数据不会被查询结果返回。
四、功能原理说明
1. 逻辑删除的SQL改写规则
逻辑删除不会真正移除数据库记录,仅修改删除标识字段。MyBatis-Plus会自动改写所有增删改查SQL:
a.新增:无变化,新增数据默认deleted = 0(未删除)
b.删除:转为UPDATE语句,SET deleted = 1,并自动追加deleted=0的过滤条件
c.修改:自动追加WHERE deleted = 0,不会修改已删除的数据
d.查询:自动追加WHERE deleted = 0,常规查询不返回已删除数据
SQL示例:
1.查询:SELECT * FROM news WHERE deleted=0
2.删除:UPDATE news SET deleted=1 WHERE id=1 AND deleted=0
2. 自动填充的执行逻辑
MyBatis-Plus在执行INSERT、UPDATE语句前,会扫描实体类的@TableField(fill)注解,调用自定义的MetaObjectHandler实现类,自动为对应字段赋值,业务代码中无需重复手动设置时间。
五、实训总结
本次实训完成了MyBatis-Plus两个企业级常用增强功能的配置:自动填充消除了时间字段重复赋值的冗余代码,逻辑删除保障了业务数据的可追溯、可恢复能力。两项功能配置完成后全局自动生效,无需在业务代码中额外处理,是后端项目的标准开发方案。

浙公网安备 33010602011771号