注解 SqlLogs
package com.ruoyi.common.annotation; import java.lang.annotation.*; /** * 获取sql注解 * * @author ruoyi */ @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface SqlLogs { /** * 是否打印sql */ public boolean hasSqlLog() default false; }
sql拦截器 SqlLogsInterceptor *参数还没处理*
package com.ruoyi.framework.config; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.toolkit.PluginUtils; import com.baomidou.mybatisplus.extension.handlers.AbstractSqlParserHandler; import com.ruoyi.common.annotation.SqlLogs; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import net.sf.jsqlparser.statement.Statement; import org.apache.commons.collections4.functors.ConstantFactory; import org.apache.ibatis.executor.Executor; 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.*; import org.apache.ibatis.reflection.MetaObject; import org.apache.ibatis.reflection.SystemMetaObject; import org.apache.ibatis.session.ResultHandler; import org.apache.ibatis.session.RowBounds; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.reflect.MethodSignature; import org.springframework.stereotype.Component; import javax.annotation.Resource; import javax.sql.DataSource; import java.lang.annotation.Annotation; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.sql.Connection; import java.util.*; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.StampedLock; @Slf4j @AllArgsConstructor //@Aspect @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}) }) @Component public class SqlLogsInterceptor extends AbstractSqlParserHandler implements Interceptor { private DataSource dataSource; private final StampedLock lock = new StampedLock(); @Override public Object intercept(Invocation invocation) throws Throwable { Map<String,Object> sqlMap = new HashMap<>(); Boolean hasSqlLogs = false; StatementHandler statementHandler = PluginUtils.realTarget(invocation.getTarget()); MetaObject metaObject = SystemMetaObject.forObject(statementHandler); this.sqlParser(metaObject); // 先判断是不是SELECT操作 不是直接过滤 MappedStatement mappedStatement = (MappedStatement) metaObject.getValue("delegate.mappedStatement"); if (!SqlCommandType.SELECT.equals(mappedStatement.getSqlCommandType())) { return invocation.proceed(); } //获取注解 来判断是否储存sql final Object[] args = invocation.getArgs(); //获取执行方法的位置 String namespace = mappedStatement.getId(); //获取mapper名称 String className = namespace.substring(0,namespace.lastIndexOf(".")); //获取方法名 String methedName= namespace.substring(namespace.lastIndexOf(".") + 1,namespace.length()); //获取当前mapper 的方法 Method[] ms = Class.forName(className).getMethods(); for(Method m : ms){ if(m.getName().equals(methedName)){ SqlLogs annotation = m.getAnnotation(SqlLogs.class); if(annotation != null){ hasSqlLogs = annotation.hasSqlLog(); } } } //如果是有注解值为true,便获取sql处理参数 if(hasSqlLogs){ BoundSql boundSql = (BoundSql) metaObject.getValue("delegate.boundSql"); // 执行的SQL语句 String originalSql = boundSql.getSql(); // SQL语句的参数 Object parameterObject = boundSql.getParameterObject(); if(parameterObject != null){ Field[] fields = parameterObject.getClass().getFields(); if(fields != null && fields.length>0){ for(Field field:fields){ field.setAccessible(true); System.err.println("获取参数: "+field.getName()); // sqlMap.put(field.getName(),field.get()); } } } System.err.println("sql :"+originalSql); } //originalSql = "select * from (" + originalSql + ") temp_data_scope where temp_data_scope." + 1 + " in (" + 2 + ")"; // metaObject.setValue("delegate.boundSql.sql", originalSql); return invocation.proceed(); } /** * 生成拦截对象的代理 * * @param target 目标对象 * @return 代理对象 */ @Override public Object plugin(Object target) { if (target instanceof StatementHandler) { return Plugin.wrap(target, this); } return target; } }
在MybatisPlusConfig中注册bean
@Bean @ConditionalOnMissingBean //有此实例便不进行注册 public SqlLogsInterceptor dataScopeInterceptor(DataSource dataSource) { return new SqlLogsInterceptor(dataSource); }
在mapper中使用注解
@SqlLogs(hasSqlLog = true) List<XgYyxxVo> selectByLqw(@Param(Constants.WRAPPER) Wrapper queryWrapper);
效果