package com.hx.mybatis.aes.springbean; import org.apache.ibatis.executor.statement.StatementHandler; import org.apache.ibatis.mapping.BoundSql; import org.apache.ibatis.mapping.MappedStatement; import org.apache.ibatis.mapping.ParameterMapping; import org.apache.ibatis.mapping.SqlCommandType; import org.apache.ibatis.plugin.*; import org.apache.ibatis.reflection.DefaultReflectorFactory; import org.apache.ibatis.reflection.MetaObject; import org.apache.ibatis.reflection.SystemMetaObject; import org.apache.ibatis.session.Configuration; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; import java.lang.reflect.Field; import java.sql.Connection; import java.util.List; import java.util.Properties; @Component @Intercepts({ @Signature( type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class }) }) public class MySqlInterceptor implements Interceptor { private static Logger logger = LoggerFactory.getLogger(MySqlInterceptor.class.getName()); @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方法的全路径名,如com.uv.dao.UserMapper.insertUser //String id = mappedStatement.getId(); //sql语句类型 select、delete、insert、update SqlCommandType sqlCommandType = mappedStatement.getSqlCommandType(); BoundSql boundSql = statementHandler.getBoundSql(); // 获取节点的配置 Configuration configuration = mappedStatement.getConfiguration(); // 获取参数 Object parameterObject = boundSql.getParameterObject(); // MetaObject主要是封装了originalObject对象,提供了get和set的方法用于获取和设置originalObject的属性值,主要支持对JavaBean、Collection、Map三种类型对象的操作 // MetaObject metaObject1 = configuration.newMetaObject(parameterObject); //获取sql中问号的基本信息 List parameterMappings = boundSql .getParameterMappings(); /*for (ParameterMapping parameterMapping : parameterMappings) { String propertyName = parameterMapping.getProperty(); System.out.println("propertyName:"+ propertyName); System.out.println("parameterObject:"+ parameterObject); }*/ //这里可以进行sql修改 //获取到原始sql语句 String sql = boundSql.getSql(); String sql2 = null; //新增 if(sqlCommandType == SqlCommandType.INSERT){ sql2 = SqlUtils.insertSql(sql, VariableAesKey.aesKeysTable); }else if(sqlCommandType == SqlCommandType.UPDATE){ sql2 = SqlUtils.updateSql(sql, VariableAesKey.aesKeysTable); }else if(sqlCommandType == SqlCommandType.SELECT){ if(VariableAesKey.isRun == 1){ sql2 = SqlUtils.selectSql(sql, VariableAesKey.aesKeysTable); }else{ sql2 = sql; } }else if(sqlCommandType == SqlCommandType.DELETE){ sql2 = SqlUtils.deleteSql(sql, VariableAesKey.aesKeysTable); }else{ sql2 = sql; } if(!"err".equals(sql2)){ //通过反射修改sql语句 Field field = boundSql.getClass().getDeclaredField("sql"); field.setAccessible(true); field.set(boundSql, sql2); } 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) { } }