【MyBatis-Plus】禁用某个方法里面查询语句的逻辑删除标记
为了解决Mybatis-plus里面有逻辑删除的标识,但是其中某些查询方法不需要过滤删除的数据,需要全部查询而实现的功能。
1、定义注解
import java.lang.annotation.*;/*** DisableLogicDelete** @author behappyto* @since 2025/4/30 9:38*/
@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface DisableLogicDelete {/*** 逻辑删除字段名称** @return 逻辑删除字段名称*/String[] value() default "del_flag";
}
2、定义切面
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.data.util.Pair;
import org.springframework.stereotype.Component;
import org.zkdn.common.annotation.DisableLogicDelete;
import org.zkdn.common.interceptor.LogicDeleteInterceptor;/*** DisableLogicDeleteAspect** @author behappyto* @since 2025/4/30 9:39*/
@Slf4j
@Aspect
@Component
public class DisableLogicDeleteAspect {/*** 切面** @param joinPoint 连接点* @param disableLogicDelete 注解* @return Object* @throws Throwable Throwable*/@Around(value = "@annotation(disableLogicDelete)")public Object around(ProceedingJoinPoint joinPoint, DisableLogicDelete disableLogicDelete) throws Throwable {try {LogicDeleteInterceptor.logicDelete.set(Pair.of(disableLogicDelete.value(), false));return joinPoint.proceed();} finally {LogicDeleteInterceptor.logicDelete.remove();}}
}
3、定义拦截逻辑
import cn.hutool.core.util.ReUtil;
import com.baomidou.mybatisplus.core.toolkit.PluginUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlCommandType;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Signature;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.SystemMetaObject;
import org.springframework.data.util.Pair;
import org.springframework.stereotype.Component;import java.sql.Connection;
import java.util.Properties;/*** LogicDeleteInterceptor** @author behappyto* @since 2025/4/30 9:42*/
@Slf4j
@Component
@Intercepts({@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class})})
public class LogicDeleteInterceptor implements Interceptor {private final static String WHERE_DEL_REG_PATTERN = "\\s*=\\s*\\S+\\s*(and|AND)*";/*** 逻辑删除*/public static ThreadLocal<Pair<String[], Boolean>> logicDelete = new ThreadLocal<>();@Overridepublic Object intercept(Invocation invocation) throws Throwable {if (!Boolean.FALSE.equals(logicDelete.get().getSecond())) {return invocation.proceed();}StatementHandler statementHandler = PluginUtils.realTarget(invocation.getTarget());MetaObject metaObject = SystemMetaObject.forObject(statementHandler);MappedStatement mappedStatement = (MappedStatement) metaObject.getValue("delegate.mappedStatement");if (!SqlCommandType.SELECT.equals(mappedStatement.getSqlCommandType())) {return invocation.proceed();}BoundSql boundSql = (BoundSql) metaObject.getValue("delegate.boundSql");String sql = boundSql.getSql();log.info("old sql:{}", sql);String[] fields = logicDelete.get().getFirst();for (String field : fields) {String delFlag = field + WHERE_DEL_REG_PATTERN;sql = ReUtil.replaceAll(sql, delFlag, "");}metaObject.setValue("delegate.boundSql.sql", sql);log.info("new sql:{}", sql);return invocation.proceed();}@Overridepublic Object plugin(Object target) {return Interceptor.super.plugin(target);}@Overridepublic void setProperties(Properties properties) {Interceptor.super.setProperties(properties);}
}
4、使用方式
在需要禁用逻辑删除的方法上面加上注解 @DisableLogicDelete,可以自定义过滤的字段