zoukankan      html  css  js  c++  java
  • (转)logback 打印Mybitis中的sql执行过程

    场景:在程序开发过程中经常需要跟踪程序中sql语句的执行过程,在控制台打印出sql语句和对应的参数传递就能够更快的定位错误!

    原文出处:http://www.cnblogs.com/beiyeren/p/4196134.html

    这里所采用的日志框架为logback

    1 不同版本的Mybitis对应不同的控制策略

    1.1 myBatis3.0.6左右的版本时

    打印sql的时候只需要配置如下属性:

    <logger name="java.sql.Connection" level="DEBUG" />
    <logger name="java.sql.Statement" level="DEBUG" />
    <logger name="java.sql.PreparedStatement" level="DEBUG" />

    源码解析:

    PreparedStatementLogger里面看这个log.isDebugEnabled()
    public Object invoke(Object proxy, Method method, Object[] params) throws Throwable {
        try {
          if (EXECUTE_METHODS.contains(method.getName())) {
            if (log.isDebugEnabled()) {
              log.debug("==>  Executing: " + removeBreakingWhitespace(sql));
              log.debug("==> Parameters: " + getParameterValueString());
            }
            clearColumnInfo();
            if ("executeQuery".equals(method.getName())) {
              ResultSet rs = (ResultSet) method.invoke(statement, params);
              if (rs != null) {
                return ResultSetLogger.newInstance(rs);
              } else {
                return null;
              }
            } else {
              return method.invoke(statement, params);
            }
          }

    这个log定义的是PreparedStatement

    private static final Log log = LogFactory.getLog(PreparedStatement.class);

    1.2 在myBatis3.2.7左右版本(以上也可以)

    只需要简单的两步即可!

    更改了打印Sql的模式,它将sql打印细化到了每一个mapperStatement的每一个方法上。

    如果你打算有一个全局配置打印所有的sql,则需要如下配置

    在mybatis的configuration中增加setting配置

    <settings>
            <setting name="logPrefix" value="dao."/>
    </settings>

     然后增加配置

    <logger name="dao" level="DEBUG"/>

    源码解析:

    ConnectionLogger
    public Object invoke(Object proxy, Method method, Object[] params)
          throws Throwable {
        try {
          if (Object.class.equals(method.getDeclaringClass())) {
            return method.invoke(this, params);
          }    
          if ("prepareStatement".equals(method.getName())) {
            if (isDebugEnabled()) {
              debug(" Preparing: " + removeBreakingWhitespace((String) params[0]), true);
            }        
            PreparedStatement stmt = (PreparedStatement) method.invoke(connection, params);
            stmt = PreparedStatementLogger.newInstance(stmt, statementLog, queryStack);
            return stmt;
          }

    其中的isDebugEnabled()指的是

    protected boolean isDebugEnabled() {
        return statementLog.isDebugEnabled();
    }

    注意这里的statementLog,看SimpleExecutor的prepareStatement(handler, ms.getStatementLog());

    public <E> List<E> doQuery(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException {
        Statement stmt = null;
        try {
          Configuration configuration = ms.getConfiguration();
          StatementHandler handler = configuration.newStatementHandler(wrapper, ms, parameter, rowBounds, resultHandler, boundSql);
          stmt = prepareStatement(handler, ms.getStatementLog());
          return handler.<E>query(stmt, resultHandler);
        } finally {
          closeStatement(stmt);
        }
      }

    这个statementLog是ms.getStatementLog()而来的。而MappedStatement的StatementLog

    String logId = id;
     if (configuration.getLogPrefix() != null) logId = configuration.getLogPrefix() + id;
     mappedStatement.statementLog = LogFactory.getLog(logId);

    这里可以看到,logPrefix决定了所有log前缀,所以只需要配置logPrefix就行了

  • 相关阅读:
    Atitit  技术经理职责与流程表总结
    Atitit.pagging  翻页功能解决方案专题 与 目录大纲 v3 r44.docx
    Atitit 翻页功能的解决方案与版本历史 v4 r49
    Atitit 数据库表文档生成解决方案
    Atiit 常见功能 常用功能与模块的最快速解决方案
    Atitit 列出wifi热点以及连接
    Atiitt 使用java语言编写sql函数或存储过程
    Atitit 数据库 标准库  sdk 函数库 编程语言 mysql oracle  attilax总结
    Atitit 纯java项目的提升进度大法通用json dsl接口
    Atitit 数据融合merge功能v3新特性.docx
  • 原文地址:https://www.cnblogs.com/lixuwu/p/6323739.html
Copyright © 2011-2022 走看看