如何使用 Mybatis-Plus 查询已经被逻辑删除的数据?
首先,我们需要自定义一个 Mybatis-Plus 的拦截器。通过实现接口,我们可以在 SQL 执行之前修改 SQL 语句。@Bean// 添加自定义的拦截器@Overridetry {// 如果 SQL 中包含 "/* no_logic_delete */" 标记// 使用 JSqlParser 解析 SQL// 如果 WHERE 子句存在,则替换逻辑删除条件= null) {
·
网上的做法比如手写xml 拼接条件last("or deleted = 0") 使用起来不太方便或是不能条件查询。现在我们将通过自定义 Mybatis-Plus 拦截器,来自动修改逻辑删除的 SQL 语句。
1. 定义自定义拦截器
首先,我们需要自定义一个 Mybatis-Plus 的拦截器。通过实现 InnerInterceptor 接口,我们可以在 SQL 执行之前修改 SQL 语句。具体步骤如下:
@AutoConfiguration
public class MybatisAutoConfiguration {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
// 添加自定义的拦截器
mybatisPlusInterceptor.addInnerInterceptor(new InnerInterceptor() {
@Override
public void beforeQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds,
ResultHandler resultHandler, BoundSql boundSql) throws SQLException {
String sql = boundSql.getSql();
try {
// 如果 SQL 中包含 "/* no_logic_delete */" 标记
if (sql.contains("/* no_logic_delete */")) {
// 使用 JSqlParser 解析 SQL
Statement statement = CCJSqlParserUtil.parse(sql);
if (statement instanceof Select) {
PlainSelect plainSelect = (PlainSelect) ((Select) statement).getSelectBody();
// 如果 WHERE 子句存在,则替换逻辑删除条件
if (plainSelect.getWhere() != null) {
String modifiedWhere = plainSelect.getWhere().toString()
.replace("DELETED = 0", "1 = 1") // 替换 "deleted = 0" 为 "1 = 1"
.replace("deleted = 0", "1 = 1"); // 处理大小写不一致的情况
plainSelect.setWhere(CCJSqlParserUtil.parseCondExpression(modifiedWhere));
}
}
// 更新 SQL
MetaObject metaObject = SystemMetaObject.forObject(boundSql);
metaObject.setValue("sql", statement.toString());
}
} catch (Exception e) {
throw new RuntimeException("SQL 解析失败", e);
}
}
});
// 添加分页插件
mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor());
return mybatisPlusInterceptor;
}
}
2. 业务代码中的使用
在实际的业务代码中,我们通过 .last("/* no_logic_delete */") 语句来动态控制是否需要绕过逻辑删除的条件。具体代码如下:
Page<IdentifiedInspectionDO> page = inspectionService.page(
new Page<IdentifiedInspectionDO>().setCurrent(reqVO.getPageNo()).setSize(reqVO.getPageSize()),
new LambdaQueryWrapper<IdentifiedInspectionDO>()
.in(IdentifiedInspectionDO::getId, reqVO.getIds())
.between(IdentifiedInspectionDO::getUpdateTime, reqVO.getUpdateTime())
.last("/* no_logic_delete */") // 添加标记,跳过逻辑删除条件
);
网上的各种绕过方式大都不可行或不方便的,希望本文能够帮助你更好地理解如何利用 Mybatis-Plus 实现查询已删除数据的需求。
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐


所有评论(0)