看到 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我不能 100% 确定你得到了什么,因为通常你会将你的 SQL 查询(参数化或非参数化)传递给 JdbcTemplate,在这种情况下你只需记录这些。如果您有PreparedStatement
s 并且您不知道正在执行哪一个,那么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查询。 我用过这对我来说适用于 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:参数值似乎打印在 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 了吗?的主要内容,如果未能解决你的问题,请参考以下文章