Mybatis不同版本sql日志打印
Mybatis不同版本sql日志打印
Small-Liu 发表于2年前
Mybatis不同版本sql日志打印
  • 发表于 2年前
  • 阅读 67
  • 收藏 0
  • 点赞 1
  • 评论 1

新睿云服务器60天免费使用,快来体验!>>>   

摘要: 带着问题看mybatis源码-不同版本sql日志打印

工作中经常希望打印mybatis执行sql的debug日志,上网找到的各种配置都不生效,这是因为mybatis版本不同日志打印方法也不同,下面谈谈开启日志的经验。

第一种方法,是把所有的日志都放开, 然后从中选取自己需要的部分;

第二种方法,从原理层解决是看mybatis源代码,找到打日志的代码,这里选取两个版本观看:

  1. 3.0.1版,

public class PreparedStatementLogger extends BaseJdbcLogger implements InvocationHandler {

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

    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());
                }
               ......//省略
            } 
        } catch (Throwable t) {
            throw ExceptionUtil.unwrapThrowable(t);
        }
    }
}

看PreparedStatementLogger的invoke方法,log是通过java.sql.PreparedStatement初始化的日志,所以log4j配置方式为:log4j.logger.java.sql.PreparedStatement=DEBUG

 2. 3.2.8版,

ConnectionLogger和PreparedStatementLogger均继承至BaseJdbcLogger,看BaseJdbcLogger的debug方法知道其log是构造方法传过来的

public abstract class BaseJdbcLogger {
    protected Log statementLog;
    public BaseJdbcLogger(Log log, int queryStack) {
        this.statementLog = log;
        if (queryStack == 0)
            queryStack = 1;
        this.queryStack = queryStack;
    }
    protected void debug(String text, boolean input) {
        if (statementLog.isDebugEnabled()) {
            statementLog.debug(prefix(input) + text);
        }
    }
}

跟踪调用栈找到该log实例是MappedStatement里面传过来的,看MappedStatement构造:

public final class MappedStatement {
    private MappedStatement() {
        // constructor disabled
    }
    public static class Builder {
        private MappedStatement mappedStatement = new MappedStatement();

        public Builder(Configuration configuration, String id, SqlSource sqlSource, SqlCommandType sqlCommandType) {
            mappedStatement.configuration = configuration;
            mappedStatement.id = id;//mappedStatement的唯一标识,namespace+id
            mappedStatement.sqlSource = sqlSource;
            mappedStatement.statementType = StatementType.PREPARED;
            mappedStatement.parameterMap = new ParameterMap.Builder(configuration, "defaultParameterMap", null,
                    new ArrayList<ParameterMapping>()).build();
            mappedStatement.resultMaps = new ArrayList<ResultMap>();
            mappedStatement.timeout = configuration.getDefaultStatementTimeout();
            mappedStatement.sqlCommandType = sqlCommandType;
            mappedStatement.keyGenerator = configuration.isUseGeneratedKeys()
                    && SqlCommandType.INSERT.equals(sqlCommandType) ? new Jdbc3KeyGenerator() : new NoKeyGenerator();
            String logId = id;
            if (configuration.getLogPrefix() != null)//可以加前缀
                logId = configuration.getLogPrefix() + id;
            //这边是构造log的地方
            mappedStatement.statementLog = LogFactory.getLog(logId);
            mappedStatement.lang = configuration.getDefaultScriptingLanuageInstance();
        }
    }
}

看log是根据MappedStatement的id创建的,这里的id是namespace+id,所以log4j的写法应该是:

log4j.logger.com.xxx.mapper=DEBUG

com.xxx.mapper是每个业务的包名,如果业务很多,就每个需要打印日志的包路径都写一遍,麻烦!看到上面代码还有一个关键元素configuration.getLogPrefix(),这个前缀是在解析配置的时候获取的,配置这个前缀就可以所以log用一个logger配置。如下:

<settings>
    <setting name="logPrefix" value="abcdefg" />
</settings>

log4j.logger.abcdefg=DEBUG

 

 

标签: mybatis
  • 打赏
  • 点赞
  • 收藏
  • 分享
共有 人打赏支持
粉丝 13
博文 56
码字总数 49976
评论 (1)
itxx2016
推荐国内最流行的iBatis、MyBatis代码生成网站: fwjava.com
在线生成,操作极其简单,生成的代码十分规范好用,经历过实战的代码.
现在,大多数知名的互联网公司都在用它.
×
Small-Liu
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: