6.18

自动填充 & 逻辑删除

一、教学目标

  1. 配置MyBatis-Plus自动填充处理器,实现createTime、updateTime字段在新增/修改时自动赋值。
  2. 结合全局配置与实体类注解,验证逻辑删除功能的完整执行效果。
  3. 区分逻辑删除与物理删除,掌握逻辑删除对增删改查SQL的自动改造规则。

二、核心知识点

  1. MetaObjectHandler:MyBatis-Plus提供的字段自动填充处理器接口,实现该接口后,框架会在SQL执行前自动为指定字段赋值,无需业务代码手动设置时间字段。
  2. @TableField(fill):实体类字段注解,通过fill属性指定字段的填充时机,常用值包括FieldFill.INSERT(仅插入时填充)、FieldFill.INSERT_UPDATE(插入和更新时均填充)。
  3. 逻辑删除:通过专用字段标记记录的删除状态,替代直接删除数据的物理删除;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. 运行测试与结果验证

  1. 测试前通过数据库管理工具查看news表,确认id=1的数据deleted字段值为0(未删除状态);
  2. 点击测试方法左侧的运行按钮,执行单元测试;
  3. 查看控制台SQL日志:实际执行的是UPDATE修改语句,而非DELETE物理删除语句;
  4. 刷新数据库表,id=1的数据deleted字段变为1,代表逻辑删除标记成功;
  5. 调用普通查询接口时,已标记删除的数据不会被查询结果返回。

四、功能原理说明

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两个企业级常用增强功能的配置:自动填充消除了时间字段重复赋值的冗余代码,逻辑删除保障了业务数据的可追溯、可恢复能力。两项功能配置完成后全局自动生效,无需在业务代码中额外处理,是后端项目的标准开发方案。

posted @ 2026-06-18 14:10  裕达  阅读(21)  评论(0)    收藏  举报