《课次26:自动填充 & 逻辑删除》学习笔记
一、教学目标
- 配置自动填充功能,实现
createTime和updateTime字段的自动赋值。 - 验证 MyBatis-Plus 的逻辑删除功能。
二、核心知识点
| 知识点 | 说明 |
|---|---|
| MetaObjectHandler | MyBatis-Plus 提供的字段自动填充处理器接口,需自定义实现类 |
| @TableField(fill) | 指定实体类字段的自动填充时机(如 INSERT、INSERT_UPDATE 等) |
| 逻辑删除 | 通过 UPDATE 修改 deleted 字段来标记删除,而非物理删除数据,查询时自动过滤已删除记录 |
三、操作步骤
本课次是在课次25的工程基础上继续操作。
1. 创建自动填充处理器
- 在
config包下新建MyMetaObjectHandler类 - 代码如下:
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;
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
@Override
public void insertFill(MetaObject metaObject) {
// 插入时自动填充 createTime 和 updateTime
this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now());
this.strictInsertFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now());
}
@Override
public void updateFill(MetaObject metaObject) {
// 更新时自动填充 updateTime
this.strictUpdateFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now());
}
}
说明:
@Component注解将该类注册为 Spring 容器中的 Bean,供 MyBatis-Plus 自动识别和使用。strictInsertFill和strictUpdateFill是 MyBatis-Plus 提供的严格填充方法,只有在实体类中存在对应字段时才会填充。
2. 确认 News 实体类中的字段
- 在课次24中已在
News实体类中添加了updateTime字段,并配置了@TableField(fill = FieldFill.INSERT_UPDATE)。 - 如果尚未添加,需在
News实体类中补充:
@TableField(fill = FieldFill.INSERT_UPDATE)
private LocalDateTime updateTime;
3. 测试逻辑删除
- 在
test文件夹中创建测试类NewsMapperTest:
import com.weitoutiao.entity.News;
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() {
int rows = newsMapper.deleteById(1); // 删除 id 为 1 的新闻
System.out.println("删除条数:" + rows);
// 控制台应输出:UPDATE news SET deleted=1 WHERE id=1
}
}
提示:代码报红时,将鼠标悬停在错误位置,选择导入对应的类即可。
4. 运行测试
- 运行
testDelete方法,控制台输出日志显示执行的 SQL 语句为UPDATE news SET deleted=1 WHERE id=1,而非DELETE FROM news。 - 在 SQLyog 中查看
news表,id=1的记录的deleted字段值变为1,表示该记录已被逻辑删除。
四、逻辑删除的概念
在实际工作中,数据非常重要,为了防止因用户误操作删除数据后无法恢复,我们通常不会对数据进行物理删除(即从数据库中直接删除),而是采用逻辑删除的方式:使用一个字段(如 deleted)来标识该记录是否已被删除,0 代表未删除,1 代表已删除。
采用逻辑删除后,SQL 语句会发生变化:
| 操作 | SQL 变化 |
|---|---|
| 插入 | 没有变化 |
| 删除 | 转变为修改操作:UPDATE 表名 SET deleted=1 WHERE id=? |
| 修改 | 需追加 WHERE deleted=0 子句,排除已删除数据 |
| 查询 | 需追加 WHERE deleted=0 子句,排除已删除数据 |
示例:
- 查询:
SELECT * FROM user WHERE deleted=0- 删除:
UPDATE user SET deleted=1 WHERE id=10 AND deleted=0
MyBatis-Plus 的@TableLogic注解会自动在查询和修改操作中追加deleted=0条件,无需手动编写。
五、笔记总结
| 步骤 | 核心内容 |
|---|---|
| 自动填充处理器 | 实现 MetaObjectHandler,重写 insertFill 和 updateFill 方法 |
| 实体类配置 | 使用 @TableField(fill = FieldFill.INSERT_UPDATE) 指定填充时机 |
| 逻辑删除测试 | deleteById 方法执行的是 UPDATE 而非 DELETE |
| 逻辑删除原理 | 通过 deleted 字段标记删除状态,查询时自动过滤 deleted=1 的记录 |
| 本课次完成了 MyBatis-Plus 自动填充和逻辑删除功能的配置与验证,这两个功能在实际项目开发中非常实用,可以大幅减少重复代码的编写,并保障数据的安全性。 |
浙公网安备 33010602011771号