web-dev-qa-db-fra.com

Voir le SQL sous-jacent dans le Spring JdbcTemplate?

J'apprends les merveilles de JdbcTemplate et de NamedParameterJdbcTemplate. J'aime ce que je vois, mais existe-t-il un moyen simple de voir le code SQL sous-jacent qu'il exécute? J'aimerais voir cela à des fins de débogage (afin de déboguer par exemple le SQL résultant dans un outil extérieur).

48
Artem

La documentation de Spring indique qu'ils sont enregistrés au niveau DEBUG:

Tous les codes SQL émis par cette classe sont enregistrés au niveau DEBUG sous catégorie correspondant au nom de la classe} qualifié complet de l'instance de modèle JdbcTemplate, mais cela peut être différent si vous utilisez une sous-classe personnalisée de la classe JdbcTemplate).

En termes XML, vous devez configurer l’enregistreur comme suit:

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

Ce sujet a cependant été discuté ici il y a un mois et il ne semble pas être aussi facile de se mettre au travail que dans Hibernate et/ou il n'a pas renvoyé les informations attendues: Spring JDBC n'enregistre pas SQL avec log4j Ce sujet sous chaque suggère d'utiliser P6Spy qui peut également être intégré à Spring selon cet article .

42
BalusC

Cela fonctionne pour moi avec org.springframework.jdbc-3.0.6.RELEASE.jar . Je ne pouvais le trouver nulle part dans la documentation du printemps (peut-être suis-je simplement paresseux) Le niveau TRACE a fait la magie.

J'utilise log4j-1.2.15 avec slf4j (1.6.4) et le fichier de propriétés pour configurer le log4j:

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

Ceci affiche l’instruction SQL et les paramètres liés comme ceci:

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

Pas sûr du type SQL inconnu mais je suppose que nous pouvons l'ignorer ici

Pour un SQL (si les valeurs des paramètres liés ne vous intéressent pas), DEBUG devrait suffire.

30
Kroky

Les valeurs des paramètres semblent être imprimées au niveau TRACE. Cela a fonctionné pour moi:

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

Sortie de la console:

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
braincell

Cela a fonctionné pour moi avec les paramètres log4j2 et 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>

La console des résultats et le journal des fichiers étaient:

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

Juste copier/coller 

HTH

2
JRichardsz

J'utilise cette ligne pour les applications Spring Boot:

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

Cette approche assez universelle et je l'utilise habituellement pour toutes les autres classes de mon application.

1
Vladislav Kysliy

Essayez d'ajouter dans 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>

vos journaux ressemblent à:

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
0
ravi

Je ne suis pas sûr à 100% de ce à quoi vous voulez en venir puisque vous allez généralement transmettre vos requêtes SQL (paramétrées ou non) au JdbcTemplate, auquel cas vous ne feriez que les enregistrer. Si vous avez PreparedStatements et que vous ne savez pas laquelle est en cours d'exécution, la méthode toString devrait fonctionner correctement. Mais pendant que nous sommes sur le sujet, il existe un paquetage Jdbc ici de Nice qui vous permettra de consigner automatiquement vos requêtes et de voir les paramètres liés à chaque fois. Très utile. La sortie ressemble à ceci:

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} 
0
danben