文档章节

Mybatis不同版本sql日志打印

Small-Liu
 Small-Liu
发布于 2016/02/26 16:35
字数 532
阅读 97
收藏 0

工作中经常希望打印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

 

 

© 著作权归作者所有

共有 人打赏支持
Small-Liu
粉丝 16
博文 56
码字总数 49976
作品 0
南京
程序员
加载中

评论(1)

i
itxx2016
推荐国内最流行的iBatis、MyBatis代码生成网站: fwjava.com
在线生成,操作极其简单,生成的代码十分规范好用,经历过实战的代码.
现在,大多数知名的互联网公司都在用它.
禁止 MyBatis 打印 SQL 的功能

背景 昨天在整理日志的时候,打算将每次执行的 SQL 打印出来(开发环境),便于快速定位问题。 在已知的两种打印方式中,MyBatis 会将预处理 SQL、参数、返回结果分别打印,而 Druid 可以更细...

闷不骚写代码
02/26
0
0
MyBatis和Hibernate相比,优势在哪里?

1、开发对比开发速度 hibernate的真正掌握要比Mybatis来得难些。Mybatis框架相对简单很容易上手,但也相对简陋些。个人觉得要用好Mybatis还是首先要先理解好Hibernate。 开发社区 Hibernate ...

park
2017/11/28
0
0
MyBatis和Hibernate优劣势对比

1、开发对比 开发速度 Hibernate的真正掌握要比Mybatis来得难些。Mybatis框架相对简单很容易上手,但也相对简陋些。个人觉得要用好Mybatis还是首先要先理解好Hibernate。 开发社区 Hibernat...

黎嘉诚
2016/08/05
88
0
MyBatis和Hibernate相比,优势在哪里?

1、开发对比开发速度 Hibernate的真正掌握要比Mybatis来得难些。Mybatis框架相对简单很容易上手,但也相对简陋些。个人觉得要用好Mybatis还是首先要先理解好Hibernate。 开发社区 Hibernate ...

vshcxl
2016/03/28
41
0
MyBatis和Hibernate相比,优势在哪里?

1、开发对比开发速度 hibernate的真正掌握要比Mybatis来得难些。Mybatis框架相对简单很容易上手,但也相对简陋些。个人觉得要用好Mybatis还是首先要先理解好Hibernate。 开发社区 Hibernate ...

qq5923dd411b8fa
06/26
0
0

没有更多内容

加载失败,请刷新页面

加载更多

这周撸了两款小程序,分享下关键点。

本周撸了两款小程序,在这里总结下开发过程中的小经验,希望对大家有用。 小程序端 我们先说小程序要注意的地方。 ##默认入口转发问题 当一个小程序Page的js文件中存在 onShareAppMessage 方...

阿北2017
20分钟前
1
0
物联网技术很新吗?不!都是旧技术

通常,当我们想到物联网时,我们会想到新的、令人兴奋的现代技术。毕竟,还有什么比不用起床就能通过智能手机告诉咖啡机开始煮晨杯的“未来”更重要呢? 多亏了物联网,我们可以在世界任何地方...

linuxCool
27分钟前
1
0
利用责任链模式设计一个拦截器

前言 近期在做 Cicada 的拦截器功能,正好用到了责任链模式。 这个设计模式在日常使用中频率还是挺高的,借此机会来分析分析。 责任链模式 先来看看什么是责任链模式。 引用一段维基百科对其...

crossoverJie
45分钟前
2
0
属性动画

透明度 alpha 平移translationX/translationY 旋转 rotation 缩放 scaleX/scaleY 多个动画一起AnimatorSet 透明度 ObjectAnimator oa = ObjectAnimator.ofFloat(iv,"alpha" ......

lanyu96
46分钟前
1
0
Docker和Kubernetes如何让DevOps更具效力

缩短time-to-makrt对于任何一家企业都至关重要,这直接决定了客户满意度、市场竞争力乃至盈利能力。但在部署应用时,大多数企业内的IT团队都或多或少会遇到Dev和Ops之间的问题,这两个部门围...

好雨云帮
55分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部