Mybatis-plus 自定义SQL注入器查询@TableLogic 逻辑删除后的数据

简介: Mybatis-plus使用@TableLogic注解进行逻辑删除数据后,在某些场景下,又需要查询该数据时,又不想写SQL。自定义Mybatis-plus的SQL注入器一劳永逸的解决该问题

方案1,继承 AbstractMethod拼接SQL语句

publicclassSelectIgnoreLogicDeleteByMapextendsAbstractMethod {
@OverridepublicMappedStatementinjectMappedStatement(Class<?>mapperClass, Class<?>modelClass, TableInfotableInfo) {
StringsqlBase="<script>SELECT %s FROM %s %s\n</script>";
StringsqlScript=this.sqlWhereByMap(tableInfo);
Stringsql=String.format(sqlBase, this.sqlSelectColumns(tableInfo, false), tableInfo.getTableName(), sqlScript);
SqlSourcesqlSource=this.languageDriver.createSqlSource(this.configuration, sql, Map.class);
returnthis.addSelectMappedStatementForTable(mapperClass, "selectIgnoreLogicDeleteByMap", sqlSource, tableInfo);
    }
/*** 拼接where条件根据map参数** [url=home.php?mod=space&uid=952169]@Param[/url] table 表* [url=home.php?mod=space&uid=155549]@Return[/url] sql*/protectedStringsqlWhereByMap(TableInfotable) {
StringsqlScript;
sqlScript=SqlScriptUtils.convertChoose("v == null", " ${k} IS NULL ", " ${k} = #{v} ");
sqlScript=SqlScriptUtils.convertForeach(sqlScript, "cm", "k", "v", "AND");
sqlScript=SqlScriptUtils.convertWhere(sqlScript);
sqlScript=SqlScriptUtils.convertIf(sqlScript, String.format("%s != null and !%s", "cm", "cm.isEmpty"), true);
returnsqlScript;
    }
}

方案2,继承 AbstractMethod拼接SQL语句

publicclassSelectIgnoreLogicDeleteextendsAbstractMethod {
@OverridepublicMappedStatementinjectMappedStatement(Class<?>mapperClass, Class<?>modelClass, TableInfotableInfo) {
StringsqlBase="<script>%s SELECT %s FROM %s %s %s %s\n</script>";
Stringsql=String.format(sqlBase, this.sqlFirst(), this.sqlSelectColumns(tableInfo, true), tableInfo.getTableName(), this.sqlWhereEntityWrapper(true, tableInfo), this.sqlOrderBy(tableInfo), this.sqlComment());
SqlSourcesqlSource=this.languageDriver.createSqlSource(this.configuration, sql, modelClass);
returnthis.addSelectMappedStatementForTable(mapperClass, "selectIgnoreLogicDelete", sqlSource, tableInfo);
    }
/*** 拼接where条件** @param newLine 新行* @param table   表* @return sql*/protectedStringsqlWhereEntityWrapper(booleannewLine, TableInfotable) {
StringsqlScript=table.getAllSqlWhere(false, true, "ew.entity.");
sqlScript=SqlScriptUtils.convertIf(sqlScript, String.format("%s != null", "ew.entity"), true);
sqlScript=sqlScript+"\n";
sqlScript=sqlScript+SqlScriptUtils.convertIf(String.format(SqlScriptUtils.convertIf(" AND", String.format("%s and %s", "ew.nonEmptyOfEntity", "ew.nonEmptyOfNormal"), false) +" ${%s}", "ew.sqlSegment"), String.format("%s != null and %s != '' and %s", "ew.sqlSegment", "ew.sqlSegment", "ew.nonEmptyOfWhere"), true);
sqlScript=SqlScriptUtils.convertWhere(sqlScript) +"\n";
sqlScript=sqlScript+SqlScriptUtils.convertIf(String.format(" ${%s}", "ew.sqlSegment"), String.format("%s != null and %s != '' and %s", "ew.sqlSegment", "ew.sqlSegment", "ew.emptyOfWhere"), true);
sqlScript=SqlScriptUtils.convertIf(sqlScript, String.format("%s != null", "ew"), true);
returnnewLine?"\n"+sqlScript : sqlScript;
    }

自定义SQL注入器,注册上述自定义的方法

publicclassCustomSqlInjectorextendsDefaultSqlInjector {
@OverridepublicList<AbstractMethod>getMethodList(Class<?>mapperClass, TableInfotableInfo) {
List<AbstractMethod>methodList=super.getMethodList(mapperClass, tableInfo);
methodList.add(newSelectIgnoreLogicDeleteByMap());
methodList.add(newSelectIgnoreLogicDelete());
returnmethodList;
    }
}

自定义基础mapper,声明注册的方法

publicinterfaceCustomBaseMapper<T>extendsBaseMapper<T> {
/*** 根据map条件查询数据,并忽略逻辑删除** @param columnMap 查询条件* @return 结果信息*/List<T>selectIgnoreLogicDeleteByMap(@Param("cm") Map<String, Object>columnMap);
/*** 根据条件查询数据,并忽略逻辑删除** @param queryWrapper 查询条件* @return 结果信息*/List<T>selectIgnoreLogicDelete(@Param("ew") Wrapper<T>queryWrapper);
}

2.使用声明的方法

业务mapper继承自定义的CustomBaseMapper

@MapperpublicinterfaceUserMapperextendsCustomBaseMapper<User> {
}

调用方法selectIgnoreLogicDelete

@OverridepublicList<User>getIgnoreDeleteById(LonguserId) {
LambdaQueryWrapper<User>queryWrapper=newLambdaQueryWrapper<>();
queryWrapper.eq(User::getId,userId);
returnthis.baseMapper.selectIgnoreLogicDelete(queryWrapper);
}

调用方法selectIgnoreLogicDeleteByMap

@OverridepublicList<User>getIgnoreDeleteById(LonguserId) {
Map<String, Object>columnMap=newHashMap<>(2);
columnMap.put("id", userId);
returnthis.baseMapper.selectIgnoreLogicDeleteByMap(columnMap);
}
目录
相关文章
|
7月前
|
SQL 人工智能 JSON
Flink 2.1 SQL:解锁实时数据与AI集成,实现可扩展流处理
简介:本文整理自阿里云高级技术专家李麟在Flink Forward Asia 2025新加坡站的分享,介绍了Flink 2.1 SQL在实时数据处理与AI融合方面的关键进展,包括AI函数集成、Join优化及未来发展方向,助力构建高效实时AI管道。
1036 43
|
7月前
|
SQL 人工智能 JSON
Flink 2.1 SQL:解锁实时数据与AI集成,实现可扩展流处理
本文整理自阿里云的高级技术专家、Apache Flink PMC 成员李麟老师在 Flink Forward Asia 2025 新加坡[1]站 —— 实时 AI 专场中的分享。将带来关于 Flink 2.1 版本中 SQL 在实时数据处理和 AI 方面进展的话题。
462 0
Flink 2.1 SQL:解锁实时数据与AI集成,实现可扩展流处理
|
8月前
|
SQL
SQL如何只让特定列中只显示一行数据
SQL如何只让特定列中只显示一行数据
|
7月前
|
SQL XML Java
通过MyBatis的XML配置实现灵活的动态SQL查询
总结而言,通过MyBatis的XML配置实现灵活的动态SQL查询,可以让开发者以声明式的方式构建SQL语句,既保证了SQL操作的灵活性,又简化了代码的复杂度。这种方式可以显著提高数据库操作的效率和代码的可维护性。
456 18
|
5月前
|
SQL 关系型数据库 MySQL
为什么这些 SQL 语句逻辑相同,性能却差异巨大?
我是小假 期待与你的下一次相遇 ~
267 0
|
7月前
|
SQL Java 数据库连接
SSM相关问题-1--#{}和${}有什么区别吗?--Mybatis都有哪些动态sql?能简述一下动 态sql的执行原理吗?--Spring支持的几种bean的作用域 Scope
在MyBatis中,`#{}`是预处理占位符,可防止SQL注入,适用于大多数参数传递场景;而`${}`是直接字符串替换,不安全,仅用于动态表名、列名等特殊场景。二者在安全性、性能及使用场景上有显著区别。
261 0
|
8月前
|
SQL
SQL中如何删除指定查询出来的数据
SQL中如何删除指定查询出来的数据
|
8月前
|
SQL 关系型数据库 MySQL
SQL如何对不同表的数据进行更新
本文介绍了如何将表A的Col1数据更新到表B的Col1中,分别提供了Microsoft SQL和MySQL的实现方法,并探讨了多表合并后更新的优化方式,如使用MERGE语句提升效率。适用于数据库数据同步与批量更新场景。
|
10月前
|
SQL XML Java
菜鸟之路Day35一一Mybatis之XML映射与动态SQL
本文介绍了MyBatis框架中XML映射与动态SQL的使用方法,作者通过实例详细解析了XML映射文件的配置规范,包括namespace、id和resultType的设置。文章还对比了注解与XML映射的优缺点,强调复杂SQL更适合XML方式。在动态SQL部分,重点讲解了`&lt;if&gt;`、`&lt;where&gt;`、`&lt;set&gt;`、`&lt;foreach&gt;`等标签的应用场景,如条件查询、动态更新和批量删除,并通过代码示例展示了其灵活性与实用性。最后,通过`&lt;sql&gt;`和`&lt;include&gt;`实现代码复用,优化维护效率。
1011 5
|
10月前
|
SQL 数据挖掘 关系型数据库
【SQL 周周练】一千条数据需要做一天,怎么用 SQL 处理电表数据(如何动态构造自然月)
题目来自于某位发帖人在某 Excel 论坛的求助,他需要将电表缴费数据按照缴费区间拆开后再按月份汇总。当时用手工处理数据,自称一千条数据就需要处理一天。我将这个问题转化为 SQL 题目。
365 12