`
zhouchaofei2010
  • 浏览: 1104015 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

mybatis出现sql异常时的日志优化-打印sql参数(版本2)

阅读更多

版本1有个问题,必须要配置mybaitis的logimp,否则会报错。重新写了了个新版本的插件拦截器,新版本的和配不配置logimp无关系,并且代码取自mybatis中的源代码,可保证正确效果

 

版本1参考地址:http://zhouchaofei2010.iteye.com/blog/2396421


 

package data.plugin;

 

import java.lang.reflect.Field;

import java.sql.PreparedStatement;

import java.util.ArrayList;

import java.util.List;

import java.util.Properties;

 

import org.apache.ibatis.executor.ErrorContext;

import org.apache.ibatis.executor.parameter.ParameterHandler;

import org.apache.ibatis.mapping.BoundSql;

import org.apache.ibatis.mapping.MappedStatement;

import org.apache.ibatis.mapping.ParameterMapping;

import org.apache.ibatis.mapping.ParameterMode;

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.scripting.defaults.DefaultParameterHandler;

import org.apache.ibatis.session.Configuration;

import org.apache.ibatis.type.TypeHandlerRegistry;

 

import comm.log.ILogger;

import comm.log.LoggerImpl;

 

@Intercepts({ @Signature(type = ParameterHandler.class, method = "setParameters", args = { PreparedStatement.class }) })

public class SQLErrorContextInterceptor implements Interceptor {

    private final ILogger logger = new LoggerImpl(this.getClass());

 

    @Override

    public Object intercept(Invocation invocation) throws Throwable {

        invocation.proceed();

        Object target=invocation.getTarget();

        if( ! (target instanceof  DefaultParameterHandler) ){

            return null;

        }

        DefaultParameterHandler hander=(DefaultParameterHandler)target;

        //获取DefaultParameterHandler中的5个属性

        Class<?> clz =hander.getClass();

        Field f = clz.getDeclaredField("mappedStatement");

        f.setAccessible(true);

        MappedStatement mappedStatement=(MappedStatement)f.get(hander);

        Configuration configuration = mappedStatement.getConfiguration();

        TypeHandlerRegistry typeHandlerRegistry=mappedStatement.getConfiguration().getTypeHandlerRegistry();

        f=clz.getDeclaredField("boundSql");

        f.setAccessible(true);

        BoundSql boundSql=(BoundSql)f.get(hander);

        Object parameterObject=hander.getParameterObject();

       

        //存储按参数顺序解析出的参数值

        List<Object> columnValues = new ArrayList<Object>();

       

        //迭代得到sql参数值

        List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();

        if (parameterMappings != null) {

          MetaObject metaObject = parameterObject == null ? null : configuration.newMetaObject(parameterObject);

          for (int i = 0; i < parameterMappings.size(); i++) {

            ParameterMapping parameterMapping = parameterMappings.get(i);

            if (parameterMapping.getMode() != ParameterMode.OUT) {

              Object value;

              String propertyName = parameterMapping.getProperty();

              if (boundSql.hasAdditionalParameter(propertyName)) { // issue #448 ask first for additional params

                value = boundSql.getAdditionalParameter(propertyName);

              } else if (parameterObject == null) {

                value = null;

              } else if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass())) {

                value = parameterObject;

              } else {

                value = metaObject == null ? null : metaObject.getValue(propertyName);

              }

              columnValues.add(value);

            }

          }

        }

        //重写ErrorContext中sql的内容,使其带上参数信息

        ErrorContext.instance().sql(boundSql.getSql() + " parameters:" + this.getParameterValueString(columnValues));

        return null;

    }

   

   

    private  String getParameterValueString(List<Object> columnValues) {

        List<Object> typeList = new ArrayList<Object>(columnValues.size());

        for (Object value : columnValues) {

          if (value == null) {

            typeList.add("null");

          } else {

            typeList.add(value + "(" + value.getClass().getSimpleName() + ")");

          }

        }

        final String parameters = typeList.toString();

        return parameters.substring(1, parameters.length() - 1);

      }

 

    @Override

    public Object plugin(Object target) {

        return Plugin.wrap(target, this);

    }

 

    @Override

    public void setProperties(Properties properties) {

 

    }

 

}

 

 

 

0
0
分享到:
评论

相关推荐

    ideal mybatis打印sql插件

    把 mybatis 输出的sql日志还原成完整的sql语句。 将日志输出的sql语句中的问号 ? 替换成真正的参数值。 通过 "Tools -&gt; MyBatis Log Plugin" 菜单或快捷键 "Ctrl+Shift+Alt+O" 启用。 点击窗口左边的 "Filter" ...

    # MybatisLog sql日志 Free-Mybatis 插件

    MybatisLog是一款针对Mybatis框架的日志插件,Free-Mybatis则是它的扩展,两者结合为开发者提供了强大的SQL日志追踪功能。在开发过程中,理解并优化SQL查询是提升应用程序性能的关键步骤,而MybatisLog与Free-...

    idea插件-mybatis-打印sql

    总之,"MyBatis Log Plugin"是针对IntelliJ IDEA用户的一款实用工具,它极大地简化了MyBatis SQL日志查看的过程,提高了开发效率。结合提供的"步骤1.png"和"步骤2.png",你可以更直观地理解安装和使用方法。对于Java...

    mybatis 日志 sql参数替换工具

    非常好用的,就是你们所要的 Mybatis日志参数快速替换占位符 sql参数替换工具html

    mybatis慢SQL插件

    拦截器监控慢SQL并将完整的可执行的SQL语句打印在日志文件中,复制该SQL语句即可在数据库工具中执行。 使用方法: 找到你springboot项目中的配置文件,增加如下配置即可 application.yml 配置如下: sql: slow...

    Mybatis Log(自动填充sql参数打印到控制台)

    在执行`getUserByUsernameAndStatus`方法时,Mybatis会自动填充SQL参数,并将完整的SQL语句(包括参数值)打印到控制台。例如,如果传入的参数是`username='test'`和`status='active'`,控制台将输出如下内容: ```...

    Mybatis日志SQL解析工具

    该工具可以将mybatis输出的sql日志提取出来,并将其格式化为可以直接执行的sql语句,节约开发人员时间

    idea mybatislog 日志打印 打印完整sql

    IntelliJ IDEA有一个名为`mybatis-log`的插件,它可以增强MyBatis的SQL日志输出,提供更友好的格式。安装该插件后,你可以在IDEA的底部工具栏看到一个新面板,显示执行的SQL和时间。 总的来说,通过配置日志框架、...

    mybatis+spring 框架中配置日志中显示sql语句

    在MyBatis与Spring整合的框架中,为了便于调试和性能优化,我们常常需要在日志中打印出执行的SQL语句。以下是如何在这样的环境中配置日志来显示SQL语句的详细步骤。 首先,我们需要了解MyBatis的日志实现。MyBatis...

    mybatisx,一款打印项目sql在日志中的插件

    1. **SQL日志打印**:插件会在日志中详细输出每个SQL语句,包括原始的SQL模板、实际的参数值以及执行后的结果,这对于理解代码与数据库交互的情况非常有帮助。 2. **执行时间统计**:MybatisX还提供了SQL执行时间的...

    mybatis SQL日志解析

    mybatis SQL日志解析;查看日志时mybatis打印的日志查询条件以及参数不是拼接好的,想复制对应sql在本地执行时比较麻烦,通过前端编写页面进行日志解析,拼接sql中的问号以及参数变课轻松实现

    MyBatis-3-User-Guide-Simplified-Chinese.rar

    MyBatis3是其最新版本,带来了许多改进和优化,旨在提高开发效率和代码的可维护性。这篇《MyBatis-3-User-Guide-Simplified-Chinese》是针对中国开发者的一份详细指南,提供了全面的MyBatis3使用方法和最佳实践。 ...

    mybatis-plus配置控制台打印完整带参数SQL语句的实现

    要使MyBatis-Plus在控制台打印带参数的SQL,我们可以选择使用`StdOutImpl`,这是一个简单的标准输出日志实现。在Spring Boot项目中,我们可以在`application.yml`或`application.properties`中进行配置。以下是两种...

    mybatis-3.2.8 mybatis-3.3.0-SNAPSHOT.jar

    2. **参数映射优化**:3.2.8版本进一步优化了参数映射机制,提高了参数绑定的效率,减少了潜在的类型转换错误。 3. **结果集映射**:支持自动结果映射,通过配置`&lt;resultMap&gt;`元素,可以轻松处理复杂的一对多、一对...

    mybatis-log-plugin:将Mybatis SQL日志还原到原始的整个可执行SQL

    把SQL日志里面的?替换为真正的参数值。 选中要还原的MyBatis日志,右键点击菜单Restore Sql,还原SQL语句. Java接口方法与Mapper xml文件互相跳转。 按钮作用 Text: 从文本内容还原SQL语句 Settings: 导航跳转开关,...

    mybatis-3.2.2-src.rar 源码

    2. **XML配置与注解**:Mybatis 使用XML或注解的方式定义SQL映射文件,这些文件包含了SQL语句及其参数绑定、结果映射等信息。开发者可以灵活地编写复杂的SQL,同时避免了大量DAO层的代码。 3. **动态SQL**:Mybatis...

    springboot+mybatis+sql日志

    在这个"springboot+mybatis+sql日志"的主题中,我们将探讨如何在Spring Boot应用中整合MyBatis,并通过Logback实现动态打印SQL日志,以及根据不同包名将日志输出到不同的文件。 首先,Spring Boot与MyBatis的集成...

    mybatis逆向工程mybatis-generator-core-1.3.2jar包

    `mybatis-generator-core-1.3.2.jar`是MBG的一个特定版本,该版本支持对数据库表进行反向工程,生成相关的Java类和XML配置,使开发者无需手动编写繁琐的DAO层代码。 在使用MBG时,我们需要创建一个配置文件(通常...

    通过Mybatis拦截器自动定位慢SQL并记录日志

    在Mybatis框架中,开发人员经常需要关注数据库查询性能,特别是慢SQL的定位与优化,因为它们直接影响到系统的响应速度和用户体验。为了有效地管理和解决这个问题,我们可以利用Mybatis的拦截器机制来自动检测并记录...

Global site tag (gtag.js) - Google Analytics