Mybatis Plus 逻辑删除(手把手教学)
一则或许对你有用的小广告
欢迎加入小哈的星球 ,你将获得:专属的项目实战 / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论
- 新项目:《从零手撸:仿小红书(微服务架构)》 正在持续爆肝中,基于
Spring Cloud Alibaba + Spring Boot 3.x + JDK 17...
,点击查看项目介绍 - 《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接: http://116.62.199.48/
截止目前, 星球 内专栏累计输出 66w+ 字,讲解图 2896+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 2300+ 小伙伴加入学习 ,欢迎点击围观
前言
大家好,我是小哈。
本小节中,我们将学习如何通过 Mybatis Plus 实现逻辑删除功能。
什么是逻辑删除?
讲逻辑删除之前,先说说物理删除。当我们想要删除数据库中的数据,都会执行一条 delete
语句,执行成功后,会将相关数据彻底从磁盘中删除掉,这种我们称之为物理删除。
逻辑删除其实并不是真正意义上的删除,它其实一条更新语句。
通常做法是在表中新增一个 is_deleted
字段,用来标识该记录的状态,默认值为 0
, 表示未删除状态,执行逻辑删除后,会将该字段更新为 1
, 表示已被删除。当然,查询的时候也会带上条件 where is_deleted = 0
, 只会查询状态未被删除的记录。
举个栗子,假设小哈跳槽了一个新公司,入职后第一天,都会在公司的 OA 系统中录入员工信息,并分配了一个员工工号,结果小哈干一个星期,发现这个公司代码写的贼烂,坑贼多,考虑再三又离职了,这时候人事会将小哈从 OA 系统的员工库中进行删除,这种情况也是逻辑删除,实际上即时你离职了,还是可以从历史员工库中调出来查看。
为什么需要逻辑删除?
逻辑删除的好处是:
- 方便恢复数据(比如小哈想明白了,重新回公司入职,更新一个数据状态就行,工号还是那个工号);
- 数据有挖掘价值(比如电商平台的订单,你虽然手动删除了订单,但是后台并不会删除,还会通过这些订单进行分析,给用户打标签,从而推荐给用户相类似的商品)
TIP : 要不要使用逻辑删除,得结合数据价值来看,如果是没有用的数据,还是物理删除比较好,能够节省磁盘空间。
Mybatis Plus 实现逻辑删除
好了,了解完逻辑删除的相关概念,我们来看看 Mybatis Plus 如何实现逻辑删除。
新建测试表
删除前面小节中用户表,重新创建一张带有逻辑删除字段的用户表,Schema 建表脚本如下:
最佳实践:逻辑删除字段请添加默认值
0
,防止后面新增数据时,还需要手动设置。
CREATE TABLE `t_user` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`name` varchar(30) COLLATE utf8mb4_bin NOT NULL DEFAULT '' COMMENT '姓名',
`age` int(11) DEFAULT NULL COMMENT '年龄',
`gender` tinyint(2) NOT NULL DEFAULT 0 COMMENT '性别,0:女 1:男',
`is_deleted` tinyint(2) NOT NULL DEFAULT 0 COMMENT '逻辑删除(0:未删除,1:已删除)',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin COMMENT='用户表';
实体类
在 model
包下创建 User
实体类:
/**
* @author: 犬小哈
* @from: 公众号:小哈学Java, 网站:www.quanxiaoha.com
* @date: 2022-12-13 14:13
* @version: v1.0.0
* @description: TODO
**/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@TableName("t_user")
public class User {
/**
* 主键 ID
*/
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
* 姓名
*/
private String name;
/**
* 年龄
*/
private Integer age;
/**
* 性别
*/
private Integer gender;
/**
* 逻辑删除
*/
@TableLogic
private Integer isDeleted;
}
注意,Mybatis Plus 提供了 @TableLogic
逻辑删除注解,只要添加在相关字段上,即可拥有逻辑删除功能。
TIP :
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
都是 Lombok 注解,偷懒用的,加上它即编译自动添加getXXX/setXXX
、类构造器
等相关方法,不了解的小伙伴可自行搜索一下如何使用。
单元测试
完成前面的工作后,我们新建单元测试,看看好不好使:
新增数据
新增一条测试数据,为后面测试做准备:
@Test
void testTableLogic() {
// 添加测试数据
User user = User.builder()
.name("犬小哈")
.age(30)
.gender(1)
.build();
userMapper.insert(user);
}
修改数据
修改记录,看看实际执行的 SQL 是什么:
@Test
void testTableLogic() {
// 根据 ID 修改记录
User user = User.builder().id(1L).name("www.quanxiaoha.com").build();
userMapper.updateById(user);
}
执行单元测试,实际执行 SQL 如下,可以看到自动附带上了逻辑删除字段的条件 is_deleted = 0
:
再来看看根据 Wrapper 条件构造器来修改记录:
@Test
void testTableLogic() {
User user1 = User.builder().name("www.quanxiaoha.com").build();
// 修改 name 等于 犬小哈 的记录
UpdateWrapper<User> wrapper = new UpdateWrapper<>();
wrapper.eq("name", "犬小哈");
userMapper.update(user1, wrapper);
}
执行单元测试,实际执行 SQL 如下, 同样也是 OK 的:
删除记录
最后看看,删除记录是不是执行了更新操作,将 is_deleted
字段更新为了 1
, 单元测试代码如下:
@Test
void testTableLogic() {
// 删除 ID 为 1 的记录
userMapper.deleteById(1L);
}
控制台打印 SQL 如下, 效果完美:
结语
本小节中,我们了解了什么是逻辑删除,以及使用逻辑删除的好处,最后演示了 Mybatis Plus 如何实现逻辑删除,还是非常方便的,简简单单一个注解就搞定了。