@Component
@Intercepts({
@Signature(
type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class
})
})
public class SqlInterceptor implements Interceptor {
@Override
public Object intercept(Invocation invocation) throws Throwable {
// 方法一
StatementHandler statementHandler = (StatementHandler) invocation.getTarget();
MetaObject metaObject = MetaObject.forObject(statementHandler, SystemMetaObject.DEFAULT_OBJECT_FACTORY,
SystemMetaObject.DEFAULT_OBJECT_WRAPPER_FACTORY, new DefaultReflectorFactory());
/*
* 先拦截到RoutingStatementHandler,里面有个StatementHandler类型的delegate变量,其实现类是BaseStatementHandler,
* 然后就到BaseStatementHandler的成员变量mappedStatement
*/
MappedStatement mappedStatement = (MappedStatement) metaObject.getValue("delegate.mappedStatement");
//id为执行的mapper方法的全路径名
// String id = mappedStatement.getId();
//sql语句类型 select、delete、insert、update
// String sqlCommandType = mappedStatement.getSqlCommandType().toString();
BoundSql boundSql = statementHandler.getBoundSql();
//获取到原始sql语句
String sql = boundSql.getSql();
String mSql = sql;
//TODO 修改位置
//注解逻辑判断 添加注解了才拦截
Class<?> classType = Class.forName(mappedStatement.getId().substring(0, mappedStatement.getId().lastIndexOf(".")));
String mName = mappedStatement.getId().substring(mappedStatement.getId().lastIndexOf(".") + 1, mappedStatement.getId().length());
for (Method method : classType.getDeclaredMethods()) {
if (method.isAnnotationPresent(SqlAnnotation.class) && mName.equals(method.getName())) {
SqlAnnotation interceptorAnnotation = method.getAnnotation(SqlAnnotation.class);
if (interceptorAnnotation.flag()) {
//可以在此处修改sql,用字符串拼接即可
SysAdmin loginAdmin = (SysAdmin)SecurityUtils.getSubject().getPrincipal();
//数据权限 admin系统权限 agent代理权限 mf厂商权限 decorate装饰公司权限
System.err.println("============sql拦截后的操作:"+mSql+"===============");
}
}
}
//通过反射修改sql语句
Field field = boundSql.getClass().getDeclaredField("sql");
field.setAccessible(true);
field.set(boundSql, mSql);
return invocation.proceed();
}
@Override
public Object plugin(Object target) {
if (target instanceof StatementHandler) {
return Plugin.wrap(target, this);
} else {
return target;
}
}
@Override
public void setProperties(Properties properties) {
}
}
/**
* 定义了一个方法层面的注解,实现局部指定拦截
*
* @author chen
*
*/
@Target({ElementType.METHOD,ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface SqlAnnotation {
boolean flag() default true;
}
在mapper上添加注解即可
@SqlAnnotation(flag = true)
List<Map<String,Object>> getListPage(DecCompany company);