看到 Spring JdbcTemplate 中的底层 SQL 了吗?

Posted

技术标签:

【中文标题】看到 Spring JdbcTemplate 中的底层 SQL 了吗?【英文标题】:Seeing the underlying SQL in the Spring JdbcTemplate? 【发布时间】:2010-12-28 06:44:29 【问题描述】:

我正在学习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) 【参考方案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-%dyyyy-MM-dd.log">
            <PatternLayout>
                <pattern>[%-5level] %dyyyy-MM-dd HH:mm:ss.SSS [%t] %c1 - %msg%n
                </pattern>
            </PatternLayout>
            <Policies>
                <TimeBasedTriggeringPolicy interval="1"
                    modulate="true" />
            </Policies>
        </RollingFile>

        <Console name="console" target="SYSTEM_OUT">
            <PatternLayout
                pattern="[%-5level] %dyyyy-MM-dd HH:mm:ss.SSS [%t] %c1 - %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。我什至无法想象为什么这应该在注释级别可用

以上是关于看到 Spring JdbcTemplate 中的底层 SQL 了吗?的主要内容,如果未能解决你的问题,请参考以下文章

学习笔记——定义切面优先级 ;Spring中的JdbcTemplate;JdbcTemplate的常用API

Spring中的JdbcTemplate

Spring 中的JdbcTemplate

Spring 中的JdbcTemplate

spring中的jdbcTemplate

如何使用 Spring Framework 中的 JdbcTemplate 类执行 INSERT 语句