依据自定义注解替换sql
import java.lang.reflect.Method;
import java.sql.Connection;
import java.util.Arrays;
import java.util.Properties;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Plugin;
import org.apache.ibatis.plugin.Signature;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.SystemMetaObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import com.api.config.annotation.ReplaceSql;
//自定义拦截器类
@Component
@Intercepts({
// @Signature(type = Executor.class,method = "query", args = { MappedStatement.class, Object.class,RowBounds.class, ResultHandler.class }),
@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class}),
// @Signature(type = ParameterHandler.class, method = "setParameters", args = PreparedStatement.class),
})
public class ReplaceSqlInterceptor implements Interceptor {
public static final Logger log = LoggerFactory.getLogger(ReplaceSqlInterceptor.class);
@Override
public Object intercept(Invocation invocation) throws Throwable {
if(invocation.getTarget() instanceof StatementHandler) {
StatementHandler statementHandler = (StatementHandler) invocation.getTarget();
MetaObject metaObject = SystemMetaObject.forObject(statementHandler);
MappedStatement mappedStatement = (MappedStatement) metaObject.getValue("delegate.mappedStatement");
if (hasAnnotation(mappedStatement.getId())){
invocation.proceed();
// 替换SQL
String originalSql = (String) metaObject.getValue("delegate.boundSql.sql");
String newSql = originalSql;
newSql = newSql.replaceAll("ISSYS", "ICSYS");
log.info("拦截后sql :" + newSql);
metaObject.setValue("delegate.boundSql.sql", newSql);
}
}
return invocation.proceed();
}
@Override
public Object plugin(Object target) {
if(target instanceof StatementHandler){
// 调用插件
return Plugin.wrap(target, this);
}
return target;
}
@Override
public void setProperties(Properties properties) {
// 设置拦截器属性
}
/**
* 判断是否有此注解
* @param classPath
* @return
* @throws ClassNotFoundException
*/
private boolean hasAnnotation(String classPath) throws ClassNotFoundException {
if(!StringUtils.hasText(classPath)){
return false;
}
//先判断类上面是否加上了注解
String mapperClass = classPath.substring(0, classPath.lastIndexOf("."));
Class<?> classType = Class.forName(mapperClass);
if(classType.isAnnotationPresent(ReplaceSql.class)){
return true;
}
//如果类上面没有加上注解,判断方法上是否加上了注解
String methodName = classPath.substring(classPath.lastIndexOf(".") + 1);
Method method1 = Arrays.stream(classType.getMethods()).filter(method -> method.equals(methodName)).findFirst().orElse(null);
if(method1 == null){
return false;
}
return method1.isAnnotationPresent(ReplaceSql.class);
}
}
自定义注解
package com.api.config.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 替换SQL中的字符串
* @author 月夜流心
*
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
public @interface ReplaceSql {
String value() default "";
}