• 源码分析之spring-JdbcTemplate日志打印sql语句


    对于开源的项目来说的好处就是我们遇到什么问题可以通过看源码来解决。

    比如近期有个同事问我说,为啥JdbcTemplate中只有在Error的时候才打印出sql语句呢。我一想,这和log的配置有关系吧。 我们的系统中使用了slf4j作为日志管理工具,之前也好像看到过项目工程中配置的日志级别是error的,所以当代码错误时打印出sql语句应该也属于正常。但是想要正常运行时也打印出sql语句,相比和配置有关,但是应该配置那个级别呢? 应该要看下JdbcTemplate的源码怎么写的,这样可快速定位配置那个日志级别(当然你可以一个一个的试)。在maven工程内看源码及其方便(个人认为用maven的唯一好处)。

    在eclipse中通过快捷键(windows系统中默认快捷键 ctrl+shift+T)打开Open Type窗口,输入JdbcTemplate后自动搜索到该类后点击进入,如果未下载过源码,maven会自动下载。在源码中找到我们经常用的execute(PreparedStatementCreator psc, PreparedStatementCallback<T> action)这个方法,然后看如下源码的第6、7、8行,使用了if(logger.isDebugEnabled)这个判断,意思是如果logger的日志级别为debug的,那么进入这个语句块,第7行获取sql的内容,第八行通过logger.debug将内容输出。由此可见我们需要配置debug级别的。然后在logger的配置文件中error修改为debug,正常输出sql语句。

     1 public <T> T execute(PreparedStatementCreator psc, PreparedStatementCallback<T> action)
     2             throws DataAccessException {
     3 
     4         Assert.notNull(psc, "PreparedStatementCreator must not be null");
     5         Assert.notNull(action, "Callback object must not be null");
     6         if (logger.isDebugEnabled()) {
     7             String sql = getSql(psc);
     8             logger.debug("Executing prepared SQL statement" + (sql != null ? " [" + sql + "]" : ""));
     9         }
    10 
    11         Connection con = DataSourceUtils.getConnection(getDataSource());
    12         PreparedStatement ps = null;
    13         try {
    14             Connection conToUse = con;
    15             if (this.nativeJdbcExtractor != null &&
    16                     this.nativeJdbcExtractor.isNativeConnectionNecessaryForNativePreparedStatements()) {
    17                 conToUse = this.nativeJdbcExtractor.getNativeConnection(con);
    18             }
    19             ps = psc.createPreparedStatement(conToUse);
    20             applyStatementSettings(ps);
    21             PreparedStatement psToUse = ps;
    22             if (this.nativeJdbcExtractor != null) {
    23                 psToUse = this.nativeJdbcExtractor.getNativePreparedStatement(ps);
    24             }
    25             T result = action.doInPreparedStatement(psToUse);
    26             handleWarnings(ps);
    27             return result;
    28         }
    29         catch (SQLException ex) {
    30             // Release Connection early, to avoid potential connection pool deadlock
    31             // in the case when the exception translator hasn't been initialized yet.
    32             if (psc instanceof ParameterDisposer) {
    33                 ((ParameterDisposer) psc).cleanupParameters();
    34             }
    35             String sql = getSql(psc);
    36             psc = null;
    37             JdbcUtils.closeStatement(ps);
    38             ps = null;
    39             DataSourceUtils.releaseConnection(con, getDataSource());
    40             con = null;
    41             throw getExceptionTranslator().translate("PreparedStatementCallback", sql, ex);
    42         }
    43         finally {
    44             if (psc instanceof ParameterDisposer) {
    45                 ((ParameterDisposer) psc).cleanupParameters();
    46             }
    47             JdbcUtils.closeStatement(ps);
    48             DataSourceUtils.releaseConnection(con, getDataSource());
    49         }
    50     }

    以上我们说的只是个例子,其实这个猜一下也大概知道应该是日志级别的配置问题。通过这个小问题我只想说的是,有时候遇到问题,不一定急着去问朋友、同事,或者google,百度,何况google那么难上去。开源的程序的话自己看下源码,问题说不行就解决了。这样对自己来说好处多多

  • 相关阅读:
    在Windows环境下搭建redis
    三种主流的Web服务实现方案(REST+SOAP+XML-RPC)简述及比较
    ASP.NET Web API身份验证和授权
    quartz 设置时间格式
    服务端发post请求产生的编码问题
    大型网站的灵魂——性能
    大型网站系统架构的演化
    c# url自动解码解决方案
    C# RSA非对称加密实现
    .net上传图片之使用第三方平台七牛上传图片接口
  • 原文地址:https://www.cnblogs.com/blacksonny/p/4605801.html
Copyright © 2020-2023  润新知