MyBatis-Plus的逻辑删除:@TableLogic与全局配置的优缺点

后端 潘老师 1个月前 (03-20) 76 ℃ (0) 扫码查看

搞Java开发的小伙伴们肯定对MyBatis-Plus不陌生,今天咱就唠唠它里面两个实用的功能:逻辑删除和批量操作。逻辑删除就像是给数据“打个标记”,而不是真的删掉;批量操作能让咱们高效处理一堆数据记录。下面直接上干货,结合代码详细讲讲!

一、MyBatis-Plus逻辑删除是啥?

逻辑删除可不是真把数据从数据库里抹掉,而是给数据加个特殊标记。比如说,在数据库表里面加个 deleted 字段,用0表示数据正常,1就表示已经被“删除”了。当咱们查询数据的时候,系统会自动把那些 deleted 字段为1的数据过滤掉;删除数据的时候,也不是真的把数据删掉,只是把这个标记改成1就行。这样一来,历史数据能保留下来,平时正常查询也不受影响,是不是很方便?

二、配置逻辑删除

MyBatis-Plus的逻辑删除功能用起来很方便,不过得先做些准备工作。

2.1 表结构设计

假设咱们有个 user 表,里面有 idusernameage 这些字段,还得有个 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会自动帮咱们处理 INSERTUPDATE 操作,像插入数据的时候,会自动把 deleted 字段设为默认的未删除值(比如0)。

七、MyBatis-Plus实现逻辑删除的优点

7.1 配置简单,开箱即用

MyBatis-Plus提供了 @TableLogic 注解和全局配置项(像 logic-delete-field 这些),就写那么几行代码,逻辑删除功能就能用起来了。不用咱们自己去写那些复杂的SQL的 UPDATE 语句和数据过滤逻辑,开发效率一下子就提高了不少。

7.2 自动过滤已删除数据

调用MyBatis-Plus的内置方法,比如 selectListselectById 这些,它会自动在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的逻辑删除功能有它的优点,也有一些不足。咱们在实际开发中,得根据项目的具体需求和情况来选择合适的方案。希望这篇文章能帮到大家,要是有啥问题,欢迎在评论区留言讨论!


版权声明:本站文章,如无说明,均为本站原创,转载请注明文章来源。如有侵权,请联系博主删除。
本文链接:https://www.panziye.com/back/16045.html
喜欢 (0)
请潘老师喝杯Coffee吧!】
分享 (0)
用户头像
发表我的评论
取消评论
表情 贴图 签到 代码

Hi,您需要填写昵称和邮箱!

  • 昵称【必填】
  • 邮箱【必填】
  • 网址【可选】