mybatis plus之逻辑删除

本文介绍如何使用MyBatis Plus实现逻辑删除功能,并通过配置避免物理删除数据。通过简单的配置及实体类注解,即可让删除操作变为更新操作,保留原有数据记录。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

MP(mybatis plus)已经大大简化了我们好多的开发操作,基本的增删改查都有了,包括代码生成等等,今天想说的是它的逻辑删除功能。我们都在数据库设计时候经常会有isDel字段,表示是否删除,为了留下客户数据,而只做逻辑删除,不做物理删除,但是MP默认的配置是物理删除,即直接调用的数据库delete操作,但是可以通过配置使调用MP的deleteXXX得方法时底层调用update操作。(以下以springboot为例)

添加配置

#逻辑删除配置
mybatis-plus.global-config.sql-injector=com.baomidou.mybatisplus.mapper.LogicSqlInjector
mybatis-plus.global-config.logic-delete-value=1
mybatis-plus.global-config.logic-not-delete-value=0

添加实体类注解

    @TableLogic
    private String isDel;

测试

调用者
此处有两个数据库操作,一个根据id查询,一个删除,期望输出两个sql,且第二个删除调用update方法。因为我的是服务间调用,如下

  @ResponseBody
    @RequestMapping("get-and-del")
    public ResultModel<Boolean> getAndDel(@RequestParam("id")String id){
        SysRole role = roleService.getById(id).getData();
        System.out.println("json role --- >"+ FastJsonUtils.toJSONString(role));
        return roleService.delById(id);
    }

被调用

   @RequestMapping("get-by-id")
    public ResultModel<SysRole> getById(@RequestParam("id")String id){
        return new ResultModel<>(ResultStatus.SUCCESS,roleService.selectById(id));
    }

    @RequestMapping("del-by-id")
    public ResultModel<Boolean> delById(@RequestParam("id")String id){
        return new ResultModel<>(ResultStatus.SUCCESS,roleService.deleteById(id));
    }

测试结果

1.png
**确实两句sql,第二个调用了update操作。重点来了,我们看上面一个根据id查询得方法,最后拼接上了 is_del=’0’.
因为我们配置了逻辑删除之后,MP自带的查询以及Update方法后都会自动加上is_del=’0’判断。**

执行前后数据库对比

删除前.png

删除后.png

<think>我们正在使用MyBatis-Plus,并且希望排除逻辑删除的字段或条件。在MyBatis-Plus中,逻辑删除通常是通过在实体类的字段上添加`@TableLogic`注解来实现的。当我们使用MyBatis-Plus提供的方法(如selectList、update等)时,框架会自动添加逻辑删除的条件(例如,只查询未删除的数据,更新时自动忽略已删除的数据等)。 但是,有时候我们可能需要排除逻辑删除的条件,例如: 1. 我们需要查询包括已删除数据在内的所有数据。 2. 我们需要更新已删除的数据。 根据MyBatis-Plus的文档和设计,我们可以通过以下几种方式来实现: ### 1. 使用条件构造器手动排除逻辑删除条件 当我们使用条件构造器(如`QueryWrapper`或`LambdaQueryWrapper`)时,可以手动覆盖逻辑删除的条件。例如,我们可以在条件构造器中使用`eq`或`ne`来明确指定逻辑删除字段的值,从而覆盖全局的逻辑删除条件。 示例代码: ```java // 假设我们的实体类中有一个逻辑删除字段,名为deleted,0表示未删除,1表示已删除 // 通常,MyBatis-Plus会自动添加条件:deleted=0 // 如果我们想查询包括已删除的数据,可以这样: List<Entity> list = entityMapper.selectList(new QueryWrapper<Entity>().eq("deleted", 0).or().eq("deleted", 1)); // 或者,我们也可以忽略deleted条件,直接查询所有(注意:这样不会添加任何关于deleted的条件,所以会查询所有状态的数据) List<Entity> list = entityMapper.selectList(new QueryWrapper<Entity>().isNull("deleted").or().isNotNull("deleted")); // 但更简单的方式是,我们直接不使用条件构造器关于逻辑删除的条件,但是MyBatis-Plus会自动添加,所以我们需要禁用自动添加。 然而,在MyBatis-Plus中,我们无法直接通过条件构造器来禁用逻辑删除的自动条件。因此,我们需要使用其他方法。 ### 2. 使用自定义SQL语句 另一种方法是使用自定义的SQL语句,在XML文件中编写SQL,这样就不会受到MyBatis-Plus逻辑删除拦截器的影响。 例如,在Mapper接口中定义方法: ```java @Select("select * from entity") List<Entity> selectAllIncludingDeleted(); ``` ### 3. 使用SqlParser注解(旧版方式,新版已弃用) 在MyBatis-Plus的旧版本中,可以使用`@SqlParser`注解来忽略逻辑删除等全局拦截器。但是在新版本中,`@SqlParser`已被弃用,替换为`@InterceptorIgnore`。 从MyBatis-Plus 3.4.0开始,可以使用`@InterceptorIgnore`注解来忽略特定的拦截器。 示例: ```java @InterceptorIgnore(tenantLine = "true", blockAttack = "true", illegalSql = "true", logicDelete = "true") public List<Entity> selectAllIncludingDeleted() { return entityMapper.selectList(null); } ``` 注意:`@InterceptorIgnore`需要在Mapper方法上使用,并且需要指定`logicDelete = "true"`来忽略逻辑删除拦截器。 但是,根据官方文档,`@InterceptorIgnore`目前支持的属性有: - tenantLine: 忽略租户拦截器 - blockAttack: 忽略攻击SQL拦截器 - illegalSql: 忽略非法SQL拦截器 - logicDelete: 是否忽略逻辑删除拦截器(3.4.0开始支持) 因此,我们可以这样写: ```java public interface EntityMapper extends BaseMapper<Entity> { @InterceptorIgnore(logicDelete = "true") List<Entity> selectAllIncludingDeleted(); } ``` 然后在service中调用这个方法,就可以忽略逻辑删除条件,查询所有数据(包括已删除的)。 ### 4. 全局配置(不推荐) 我们也可以临时修改全局配置,但是这样会影响整个应用,不推荐。 ### 总结 根据需求,如果我们只是偶尔需要排除逻辑删除条件,建议使用`@InterceptorIgnore`注解在Mapper方法上忽略逻辑删除拦截器。如果我们需要在条件构造器中灵活控制,可以尝试在条件构造器中手动覆盖逻辑删除条件(但要注意,MyBatis-Plus的自动条件可能会与我们手动的条件冲突,所以最好使用自定义SQL或`@InterceptorIgnore`)。 另外,对于更新操作,如果我们想要更新已经被逻辑删除的记录,同样可以使用`@InterceptorIgnore`注解来忽略逻辑删除拦截器,或者使用自定义SQL。 注意:忽略逻辑删除条件可能会带来数据安全的问题,请确保在业务中明确知道这样做的后果。 引用[1]中提到了`@TableField`注解,其中有一个属性`condition`用于预处理WHERE实体条件自定义运算规则,但这里我们关注的是逻辑删除的全局条件,所以不适用。 引用[2]是关于主键生成器的自定义,与逻辑删除无关。 引用[3]是MyBatis-Plus的官网,我们可以查阅更多关于逻辑删除和拦截器忽略的文档。 因此,针对问题“如何排除逻辑删除的字段或条件”,我们推荐使用`@InterceptorIgnore(logicDelete = "true")`注解。 §§相关问题§§ 1. 如何在MyBatis-Plus中配置逻辑删除? 2. `@InterceptorIgnore`注解还可以用来忽略哪些拦截器? 3. 在MyBatis-Plus中,除了逻辑删除,还有哪些常用的拦截器?</think>### MyBatis-Plus 排除逻辑删除字段或条件的方法 在 MyBatis-Plus 中排除逻辑删除字段或条件,可通过以下方式实现: #### 方法一:使用 `@InterceptorIgnore` 注解(推荐) 在 Mapper 方法上添加注解,直接忽略逻辑删除拦截器: ```java @InterceptorIgnore(logicDelete = "true") // 忽略逻辑删除条件 @Select("SELECT * FROM user") List<User> selectAllWithDeleted(); ``` 此方法会跳过自动添加的逻辑删除条件(如 `WHERE deleted=0`),查询包含已删除数据[^1]。 #### 方法二:自定义 SQL 语句 在 XML 或注解中编写完整 SQL,手动控制条件: ```xml <!-- XML 示例 --> <select id="selectRawList" resultType="User"> SELECT id, name, deleted FROM user WHERE name LIKE '%test%' <!-- 不自动添加逻辑删除条件 --> </select> ``` #### 方法三:条件构造器忽略字段 通过 `QueryWrapper` 的 `select()` 方法排除逻辑删除字段: ```java QueryWrapper<User> wrapper = new QueryWrapper<>(); wrapper.select("id", "name") // 显式指定字段,排除逻辑删除字段 .like("name", "test"); List<User> list = userMapper.selectList(wrapper); ``` #### 方法四:实体注解配置 在实体类中,通过 `@TableField` 标记逻辑删除字段为非数据库字段: ```java public class User { @TableField(exist = false) // 声明此字段非数据库字段 private Integer deleted; } ``` 此时 MyBatis-Plus 会完全忽略该字段,不参与任何 SQL 生成[^1]。 --- ### 逻辑删除配置说明 1. **全局配置**(在 `application.yml` 中): ```yaml mybatis-plus: global-config: db-config: logic-delete-field: deleted # 逻辑删除字段名(默认 deleted) logic-not-delete-value: 0 # 未删除值 logic-delete-value: 1 # 已删除值 ``` 2. **局部配置**(实体类注解): ```java @TableLogic(value = "0", delval = "1") // 定义逻辑删除值 private Integer deleted; ``` > ⚠️ **注意事项** > - 方法一(`@InterceptorIgnore`)需 MyBatis-Plus 3.4+ 版本支持 > - 忽略逻辑删除后,请注意数据安全性,避免误操作已删除数据 > - 更新操作时需手动过滤逻辑删除字段,防止字段被更新 [^1]: MyBatis-Plus 官方字段注解配置 [^3]: MyBatis-Plus 核心功能文档
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值