【问题标题】:Seeing the underlying SQL in the Spring JdbcTemplate?看到 Spring JdbcTemplate 中的底层 SQL 了吗?
【发布时间】:2023-03-03 02:54:01
【问题描述】:

我正在学习JdbcTemplate和NamedParameterJdbcTemplate的神奇之处。我喜欢我所看到的,但是有什么简单的方法可以查看它最终执行的底层 SQL 吗?我希望看到这个用于调试目的(例如为了在外部工具中调试生成的 SQL)。

【问题讨论】:

  • 澄清一下,我希望看到带有“?”的 SQL确保整个过程正常运行。
  • 嗨 Artem,你在你的代码中实现了吗?
  • 如果使用 Intellij Debugger,请按 double shift,输入:org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate#query(java.lang.String, org.springframework.jdbc.core.namedparam. SqlParameterSource, org.springframework.jdbc.core.RowMapper)

标签: sql jdbc spring-jdbc


【解决方案1】:

我不能 100% 确定你得到了什么,因为通常你会将你的 SQL 查询(参数化或非参数化)传递给 JdbcTemplate,在这种情况下你只需记录这些。如果您有PreparedStatements 并且您不知道正在执行哪一个,那么toString 方法应该可以正常工作。但是当我们讨论这个主题时,有一个不错的 Jdbc 记录器包here,它可以让您自动记录您的查询以及每次查看绑定的参数。很有用。输出如下所示:

executing PreparedStatement: 'insert into ECAL_USER_APPT
(appt_id, user_id, accepted, scheduler, id) values (?, ?, ?, ?, null)'
     with bind parameters: {1=25, 2=49, 3=1, 4=1} 

【讨论】:

  • PreparedStatement#toString() 将返回 SQL 字符串在 JDBC API 中没有指定,因此是一个实现细节。您取决于 JDBC 驱动程序的品牌和/或版本是否有效。
  • 您在评论中引用的指向rkbloom.net/logdriver 的链接现在似乎已失效。您能否提供有关此记录器的更多详细信息 - 我在父站点上找不到任何参考。谢谢
  • 包含该解决方案的链接不起作用,因此该解决方案的投票率很低。
【解决方案2】:

Spring documentation 表示他们在 DEBUG 级别记录:

该类发出的所有 SQL 都记录在 DEBUG 级别下的 category 对应于完全限定的 class name模板实例(通常是 JdbcTemplate,但如果您使用 JdbcTemplate 类的自定义子类,它可能会有所不同)。

在 XML 术语中,您需要像这样配置记录器:

<category name="org.springframework.jdbc.core.JdbcTemplate">
    <priority value="debug" />
</category>

然而,这个主题是一个月前在这里讨论过的,它似乎不像在 Hibernate 中那么容易开始工作和/或它没有返回预期的信息:Spring JDBC is not logging SQL with log4j 每个下面的这个主题都建议使用 P6Spy也可以根据this article集成到Spring中。

【讨论】:

  • 用作名称“org.springframework.jdbc”,也可以查看真正的SQL查询。
  • 我用过
  • 如果我想在单个日志语句中看到多行 SQL 怎么办?
【解决方案3】:

这对我来说适用于 org.springframework.jdbc-3.0.6.RELEASE.jar。 我在 Spring 文档中的任何地方都找不到这个(也许我只是懒惰),但我发现(反复试验)TRACE 级别起到了神奇的作用。

我正在使用 log4j-1.2.15 以及 slf4j (1.6.4) 和属性文件来配置 log4j:

log4j.logger.org.springframework.jdbc.core = TRACE

这将显示 SQL 语句和绑定参数,如下所示:

Executing prepared SQL statement [select HEADLINE_TEXT, NEWS_DATE_TIME from MY_TABLE where PRODUCT_KEY = ? and NEWS_DATE_TIME between ? and ? order by NEWS_DATE_TIME]
Setting SQL statement parameter value: column index 1, parameter value [aaa], value class [java.lang.String], SQL type unknown
Setting SQL statement parameter value: column index 2, parameter value [Thu Oct 11 08:00:00 CEST 2012], value class [java.util.Date], SQL type unknown
Setting SQL statement parameter value: column index 3, parameter value [Thu Oct 11 08:00:10 CEST 2012], value class [java.util.Date], SQL type unknown

不确定 SQL 类型未知,但我想我们可以在这里忽略它

对于一个 SQL(即,如果您对绑定参数值不感兴趣)DEBUG 就足够了。

【讨论】:

  • 我认为这可能适用于 jdbc,但没有 jdbctemplate。也不适合我
  • 对我来说,这适用于 Spring 4.2.4 和 JdbcTemplate
  • 它也适用于 logback:
【解决方案4】:

参数值似乎打印在 TRACE 级别。这对我有用:

log4j.logger.org.springframework.jdbc.core.JdbcTemplate=DEBUG, file
log4j.logger.org.springframework.jdbc.core.StatementCreatorUtils=TRACE, file

控制台输出:

02:40:56,519 TRACE http-bio-8080-exec-13 core.StatementCreatorUtils:206 - Setting SQL statement parameter value: column index 1, parameter value [Tue May 31 14:00:00 CEST 2005], value class [java.util.Date], SQL type unknown
02:40:56,528 TRACE http-bio-8080-exec-13 core.StatementCreatorUtils:206 - Setting SQL statement parameter value: column index 2, parameter value [61], value class [java.lang.Integer], SQL type unknown
02:40:56,528 TRACE http-bio-8080-exec-13 core.StatementCreatorUtils:206 - Setting SQL statement parameter value: column index 3, parameter value [80], value class [java.lang.Integer], SQL type unknown

【讨论】:

    【解决方案5】:

    这对我来说适用于 log4j2 和 xml 参数:

    <?xml version="1.0" encoding="UTF-8"?>
    <Configuration status="debug">
        <Properties>
            <Property name="log-path">/some_path/logs/</Property>
            <Property name="app-id">my_app</Property>
        </Properties>
    
        <Appenders>
            <RollingFile name="file-log" fileName="${log-path}/${app-id}.log"
                filePattern="${log-path}/${app-id}-%d{yyyy-MM-dd}.log">
                <PatternLayout>
                    <pattern>[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n
                    </pattern>
                </PatternLayout>
                <Policies>
                    <TimeBasedTriggeringPolicy interval="1"
                        modulate="true" />
                </Policies>
            </RollingFile>
    
            <Console name="console" target="SYSTEM_OUT">
                <PatternLayout
                    pattern="[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n" />
            </Console>
        </Appenders>
        <Loggers>
    
            <Logger name="org.springframework.jdbc.core" level="trace" additivity="false">
                <appender-ref ref="file-log" />
                <appender-ref ref="console" />
            </Logger>
    
            <Root level="info" additivity="false">
                <appender-ref ref="file-log" />
                <appender-ref ref="console" />
            </Root>
        </Loggers>
    
    </Configuration>
    

    结果控制台和文件日志为:

    JdbcTemplate - Executing prepared SQL query
    JdbcTemplate - Executing prepared SQL statement [select a, b from c where id = ? ]
    StatementCreatorUtils - Setting SQL statement parameter value: column index 1, parameter value [my_id], value class [java.lang.String], SQL type unknown
    

    只是复制/过去

    HTH

    【讨论】:

      【解决方案6】:

      尝试在 log4j.xml 中添加

      <!--  enable query logging -->
      <category name="org.springframework.jdbc.core.JdbcTemplate">
          <priority value="DEBUG" />
      </category>
      
      <!-- enable query logging for SQL statement parameter value -->
      <category name="org.springframework.jdbc.core.StatementCreatorUtils">
          <priority value="TRACE" />
      </category>
      

      您的日志如下所示:

      DEBUG JdbcTemplate:682 - Executing prepared SQL query
      DEBUG JdbcTemplate:616 - Executing prepared SQL statement [your sql query]
      TRACE StatementCreatorUtils:228 - Setting SQL statement parameter value: column index 1, parameter value [param], value class [java.lang.String], SQL type unknown
      

      【讨论】:

        【解决方案7】:

        我将此行用于 Spring Boot 应用程序:

        logging.level.org.springframework.jdbc.core = TRACE
        

        这种方法非常普遍,我通常将它用于我的应用程序中的任何其他类。

        【讨论】:

        • 请在注释级别告诉我..我没有任何 xml 或属性文件..
        • 2020 年都是关于注释的幸运或不幸
        • 我认为没有办法用注释来做到这一点,只有属性文件或 logback.xml。我什至无法想象为什么这应该在注释级别可用
        猜你喜欢
        • 2014-09-13
        • 2019-10-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多