mybatis(mybatis-plus)使用sql拦截器和自定义注解获取sql和参数
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了mybatis(mybatis-plus)使用sql拦截器和自定义注解获取sql和参数,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含4703字,纯文字阅读大概需要7分钟。
内容图文
注解 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);
效果
内容总结
以上是互联网集市为您收集整理的mybatis(mybatis-plus)使用sql拦截器和自定义注解获取sql和参数全部内容,希望文章能够帮你解决mybatis(mybatis-plus)使用sql拦截器和自定义注解获取sql和参数所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。