MyBatis-Plus的逻辑删除:@TableLogic与全局配置的优缺点
搞Java开发的小伙伴们肯定对MyBatis-Plus不陌生,今天咱就唠唠它里面两个实用的功能:逻辑删除和批量操作。逻辑删除就像是给数据“打个标记”,而不是真的删掉;批量操作能让咱们高效处理一堆数据记录。下面直接上干货,结合代码详细讲讲!
一、MyBatis-Plus逻辑删除是啥?
逻辑删除可不是真把数据从数据库里抹掉,而是给数据加个特殊标记。比如说,在数据库表里面加个 deleted
字段,用0表示数据正常,1就表示已经被“删除”了。当咱们查询数据的时候,系统会自动把那些 deleted
字段为1的数据过滤掉;删除数据的时候,也不是真的把数据删掉,只是把这个标记改成1就行。这样一来,历史数据能保留下来,平时正常查询也不受影响,是不是很方便?
二、配置逻辑删除
MyBatis-Plus的逻辑删除功能用起来很方便,不过得先做些准备工作。
2.1 表结构设计
假设咱们有个 user
表,里面有 id
、username
、age
这些字段,还得有个 deleted
字段(类型是int),用来表示数据是否被删除。0代表正常,1就代表被删除了。
2.2 实体类配置
在实体类里,得加个 @TableLogic
注解。看下面这段代码:
import com.baomidou.mybatisplus.annotation.TableLogic; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; // 下面这个User类是和数据库中user表对应的实体类 // @Data注解能自动生成getter、setter等方法,方便操作属性 // @TableName指定了对应的数据库表名 @Data @TableName("user") public class User { private Long id; private String username; private Integer age; // @TableLogic注解标记这个字段是逻辑删除字段 @TableLogic private Integer deleted; }
2.3 全局配置(可选)
要是想统一设置逻辑删除的相关参数,还可以在 application.yml
里进行全局配置:
mybatis-plus: global-config: db-config: logic-delete-field: deleted # 全局逻辑删除字段 logic-delete-value: 1 # 删除时的值 logic-not-delete-value: 0 # 未删除时的值
加了这个全局配置之后,实体类里的 @TableLogic
注解就可以不写了,系统会默认按照全局配置来。
2.4 Mapper配置
Mapper还是老样子,继承 BaseMapper
就行:
public interface UserMapper extends BaseMapper<User> { }
三、实战:逻辑删除操作
配置好之后,就可以来试试逻辑删除的效果了。逻辑删除主要用 deleteById
或者 delete
方法,MyBatis-Plus会自动把这些删除操作转成 UPDATE
操作。
3.1 单个删除
@SpringBootTest class LogicDeleteTest { // 自动注入UserMapper,方便调用里面的方法操作数据库 @Autowired private UserMapper userMapper; // 这个测试方法用来测试根据id进行逻辑删除的功能 @Test void testDeleteById() { userMapper.deleteById(1L); System.out.println("ID=1 的用户被逻辑删除了!"); } }
执行完这段代码,去数据库里看,这条记录的 deleted
字段就变成1了,但数据其实还在数据库里。MyBatis-Plus实际执行的SQL是这样的:
UPDATE user SET deleted=1 WHERE id=1 AND deleted=0
3.2 条件删除
@Test void testDeleteByCondition() { userMapper.delete(new QueryWrapper<User>().eq("age", 25)); System.out.println("25岁的都被逻辑删了!"); }
对应的SQL语句是:
UPDATE user SET deleted=1 WHERE age=25 AND deleted=0
四、查询时自动过滤
逻辑删除还有个好处,就是查询数据的时候,系统会自动带上 deleted=0
(或者你配置的未删除值)这个条件。看下面这个查询代码:
@Test void testSelect() { List<User> users = userMapper.selectList(null); users.forEach(System.out::println); }
执行的SQL语句是:
SELECT id, username, age, deleted FROM user WHERE deleted=0
这样一来,被删除的数据就不会出现在查询结果里,咱们就不用手动去加这个过滤条件了,是不是很省心?
五、想查已删除的数据怎么办?
有时候,咱们可能需要查看那些被逻辑删除的数据,这时候就得动点小脑筋了。
一种方法是自定义SQL语句:
@Select("SELECT * FROM user WHERE deleted=1") List<User> selectDeleted();
还有一种方法,就是用 Wrapper
来跳过逻辑删除:
@Test void testSelectWithDeleted() { List<User> users = userMapper.selectList(new QueryWrapper<User>().eq("deleted", 1)); users.forEach(System.out::println); }
六、使用MyBatis-Plus逻辑删除的注意点
用MyBatis-Plus做逻辑删除,有些地方得注意。
首先,逻辑删除只对MyBatis-Plus自带的方法生效。要是自己写SQL语句,比如用 @Select
或者 @Update
,就得自己手动处理 deleted
字段,不然很容易出问题。
其次,配置好逻辑删除字段之后,MyBatis-Plus会自动帮咱们处理 INSERT
和 UPDATE
操作,像插入数据的时候,会自动把 deleted
字段设为默认的未删除值(比如0)。
七、MyBatis-Plus实现逻辑删除的优点
7.1 配置简单,开箱即用
MyBatis-Plus提供了 @TableLogic
注解和全局配置项(像 logic-delete-field
这些),就写那么几行代码,逻辑删除功能就能用起来了。不用咱们自己去写那些复杂的SQL的 UPDATE
语句和数据过滤逻辑,开发效率一下子就提高了不少。
7.2 自动过滤已删除数据
调用MyBatis-Plus的内置方法,比如 selectList
、selectById
这些,它会自动在SQL语句里加上 WHERE deleted=0
(或者你配置的未删除值)这个条件。咱们写业务代码的时候,都不用改,查询出来的结果天然就把已删除的数据过滤掉了。
7.3 默认值自动填充
插入数据的时候,MyBatis-Plus会自动给 deleted
字段填上未删除值(一般就是0);更新数据的时候,也能智能处理这个字段,不用咱们手动去维护,省了不少事儿。
7.4 统一性强
通过全局配置,所有的表都能共用一套逻辑删除规则,比如说逻辑删除字段名、删除值这些。团队一起开发的时候,大家的代码风格统一,后期维护起来也轻松很多。
7.5 与物理删除切换方便
要是项目里有张表不想用逻辑删除了,把 @TableLogic
注解去掉,或者调整一下配置,MyBatis-Plus就能切换成物理删除模式,灵活性还是挺强的。
八、MyBatis-Plus实现逻辑删除的缺点
8.1 自定义SQL不受控
前面也提到过,逻辑删除只对MyBatis-Plus的内置方法生效。要是自己手写SQL语句,像用 @Select
或者 @Update
这些注解写的SQL,系统不会自动给加上 deleted
条件,得咱们自己手动处理。这就很容易出现遗漏,一不注意就可能出问题。
8.2 全局配置不够灵活
有些项目里,不同的表可能需要不同的逻辑删除字段或者值。比如说,有的表用 is_deleted
作为逻辑删除字段,有的表用 deleted
。这时候,全局配置就不太好用了,只能在每张表的实体类里单独加 @TableLogic
注解来覆盖全局配置,感觉有点繁琐。
8.3 存在性能隐患
MyBatis-Plus只是实现了逻辑删除的标记和数据过滤功能,但是数据长期积累下来,数据库表可能会越来越大,这个问题它可解决不了。还得咱们开发者自己去做定时清理或者归档,MyBatis-Plus本身没提供这方面的解决方案。
8.4 调试难度增加
因为逻辑删除操作实际上是转成了 UPDATE
操作,所以在日志里看到的SQL语句不像物理删除那么直观。排查问题的时候,可能得仔细多看几眼,确认各个字段的状态,增加了调试的复杂性。
8.5 字段依赖强
逻辑删除功能依赖实体类里的 deleted
字段。要是数据库表结构里没加这个字段,或者字段名和实体类里的不一致,MyBatis-Plus的逻辑删除功能就没法正常工作了。所以数据库设计的时候,得严格和实体类里的字段对齐。
MyBatis-Plus的逻辑删除功能有它的优点,也有一些不足。咱们在实际开发中,得根据项目的具体需求和情况来选择合适的方案。希望这篇文章能帮到大家,要是有啥问题,欢迎在评论区留言讨论!