Видя основной SQL в Spring JdbcTemplate?

Я узнаю о чудесах JdbcTemplate и NamedParameterJdbcTemplate. Мне нравится то, что я вижу, но есть ли простой способ увидеть базовый SQL, который он выполняет? Я хотел бы видеть это в целях отладки (например, для отладки результирующего SQL во внешнем инструменте).

9 ответов

Решение

В документации Spring говорится, что они зарегистрированы на уровне DEBUG:

Весь SQL, выпущенный этим классом, регистрируется на уровне DEBUG в категории, соответствующей полностью определенному имени класса экземпляра шаблона (обычно JdbcTemplate, но он может отличаться, если вы используете пользовательский подкласс класса JdbcTemplate).

В терминах XML вам необходимо настроить регистратор примерно так:

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

Эта тема, однако, обсуждалась здесь месяц назад, и кажется, что работать не так просто, как в Hibernate, и / или она не возвращает ожидаемую информацию: Spring JDBC не регистрирует SQL с помощью log4j. В этом разделе под каждым предлагается использовать P6Spy. который также может быть интегрирован в Spring согласно этой статье.

Это работает для меня с 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 должно быть достаточно.

Я использую эту строку для приложений Spring Boot:

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

Этот подход довольно универсален, и я обычно использую его для любых других классов внутри моего приложения.

Значения параметров, похоже, печатаются на уровне TRACE. Это сработало для меня:

log4j.logger.org.springframework.jdbc.core.JdbcTem plate=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

Это работало для меня с параметрами 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

Просто скопируйте / прошлое

НТН

Попробуйте добавить в 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

Если вы используете ch.qos.logback, добавьте регистратор:

        <logger name="org.springframework.jdbc.core" level="trace"/>

Я не уверен на 100%, к чему вы клоните, поскольку обычно вы передаете свои SQL-запросы (параметризованные или нет) на JdbcTemplate, и в этом случае вы просто регистрируете их. Если у вас есть PreparedStatement S, и вы не знаете, какой из них выполняется, toString метод должен работать нормально. Но в то время как мы находимся на предмете, есть хороший пакет регистратора Jdbc, который позволит вам автоматически регистрировать ваши запросы, а также видеть связанные параметры каждый раз. Очень полезно. Вывод выглядит примерно так:

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} 

Это можно сделать без какой-либо конфигурации xml или yml, но так же просто, как только чистый код Java, как показано ниже:

      import org.slf4j.LoggerFactory;
import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.Logger;

Logger logger = (Logger) LoggerFactory.getLogger("org.springframework.jdbc.core.JdbcTemplate");
logger.setLevel(Level.valueOf("DEBUG"));

// Or ,for more datasource details,you can retrieve another logger  like this 
// Logger logger2 = (Logger) LoggerFactory.getLogger("org.springframework.jdbc");
//logger2.setLevel(Level.valueOf("DEBUG"));

Наслаждайтесь этим, ребята, смотрите больше здесь https://www.bswen.com/2019/05/springboot-How-to-print-JPA-and-jdbcTemplate-SQL-logs.html

Другие вопросы по тегам