Comment enregistrer des instructions SQL dans Spring Boot?

342

Je souhaite enregistrer les instructions SQL dans un fichier.
J'ai les propriétés suivantes dansapplication.properties

spring.datasource.url=...
spring.datasource.username=user
spring.datasource.password=1234
spring.datasource.driver-class-name=net.sourceforge.jtds.jdbc.Driver

spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true

security.ignored=true
security.basic.enabled=false

logging.level.org.springframework.web=INFO
logging.level.org.hibernate=INFO
logging.file=c:/temp/my-log/app.log

Quand j'exécute mon application

cmd>mvn spring-boot:run

Je peux voir les instructions SQL dans la console, mais elles n'apparaissent pas dans un fichier app.log. Le fichier contient uniquement les journaux de base du printemps.

Que dois-je faire pour voir les instructions SQL dans le fichier journal?

Oleg Pavliv
la source

Réponses:

458

essayez d'utiliser ceci dans votre fichier de propriétés:

logging.level.org.hibernate.SQL=DEBUG
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE
Paul Woods
la source
74
Si vous voulez aussi enregistrer des valeurs:logging.level.org.hibernate.type=TRACE
elysch
2
Mais cela enregistre seulement quelques valeurs de liaison. Comment puis-je enregistrer les valeurs de l'API critères? Si j'utilise des spécifications, je n'obtiens aucune sortie pour les paramètres liés créés avec CriteriaBuilder.
Josh
204

Cela fonctionne aussi pour stdout:

spring.jpa.properties.hibernate.show_sql=true
spring.jpa.properties.hibernate.use_sql_comments=true
spring.jpa.properties.hibernate.format_sql=true

Pour enregistrer des valeurs:

logging.level.org.hibernate.type=trace

Ajoutez simplement ceci à application.properties.

v.ladynev
la source
11
Si vous voulez aussi enregistrer des valeurs:spring.jpa.properties.hibernate.type=trace
elysch
1
Cela n'écrit pas dans le fichier journal, cela écrit dans STDOUT
Muhammad Hewedy
4
Je ne vois toujours qu'à la ?place des paramètres. Cette solution était-elle censée me les montrer?
Adeynack
1
spring.jpa.properties.hibernate.type = trace n'affecte pas mon fichier journal; (
gstackoverflow
1
Le "type = trace" n'est pas une propriété de ressort, donc cela ne fonctionne pas. La solution donnée ci-dessous stackoverflow.com/a/41594913/5107365 est la bonne pour cela.
Raj
97

Cela fonctionne pour moi (YAML):

spring:
  jpa:
    properties:
      hibernate:
        show_sql: true
        format_sql: true
logging:
  level:
    org:
      hibernate:
        type: trace
Michel
la source
18

Veuillez utiliser:

logging.level.org.hibernate.SQL=DEBUG
logging.level.org.hibernate.type=TRACE
spring.jpa.show-sql=true
rahulnikhare
la source
4
logging.level.org.hibernate.SQL=DEBUGfait fonctionner pour moi et manquait pour d'autres réponses. Merci!
Vic
18

si vous avez un logback-spring.xml ou quelque chose comme ça, ajoutez-y le code suivant

<logger name="org.hibernate.SQL" level="trace" additivity="false">
    <appender-ref ref="file" />
</logger>

travaille pour moi.

Pour obtenir également des variables de liaison:

<logger name="org.hibernate.type.descriptor.sql" level="trace">
    <appender-ref ref="file" />
</logger>
Edye Chan
la source
1
Avec Spring Boot, vous devez utiliser<appender-ref ref="FILE" />
Ortomala Lokni
appender ref est le nom de l'appender que vous avez défini dans le xml logback. Ce n'est qu'une variable
Raja Anbazhagan
17

Puisque c'est une question très courante, j'ai écrit cet article , sur lequel cette réponse est basée.

Paramètres à éviter

Vous ne devez pas utiliser ce paramètre:

spring.jpa.show-sql=true 

Le problème show-sqlest que les instructions SQL sont imprimées dans la console, il n'y a donc aucun moyen de les filtrer, comme vous le feriez normalement avec un cadre de journalisation.

Utilisation de la journalisation Hibernate

Dans votre fichier de configuration de journal, si vous ajoutez l'enregistreur suivant:

<logger name="org.hibernate.SQL" level="debug"/>

Ensuite, Hibernate imprimera les instructions SQL lors de la création du JDBC PreparedStatement. C'est pourquoi l'instruction sera enregistrée à l'aide des espaces réservés de paramètre:

INSERT INTO post (title, version, id) VALUES (?, ?, ?)

Si vous souhaitez enregistrer les valeurs des paramètres de liaison, ajoutez simplement également l'enregistreur suivant:

<logger name="org.hibernate.type.descriptor.sql.BasicBinder" level="trace"/>

Une fois que vous avez défini l' BasicBinderenregistreur, vous verrez que les valeurs des paramètres de liaison sont également enregistrées:

DEBUG [main]: o.h.SQL - insert into post (title, version, id) values (?, ?, ?)
TRACE [main]: o.h.t.d.s.BasicBinder - binding parameter [1] as [VARCHAR] - [High-Performance Java Persistence, part 1]
TRACE [main]: o.h.t.d.s.BasicBinder - binding parameter [2] as [INTEGER] - [0]
TRACE [main]: o.h.t.d.s.BasicBinder - binding parameter [3] as [BIGINT] - [1]

Utilisation de proxy de source de données

Le proxy de source de données vous permet de proxy le JDBC réel DataSource, comme illustré par le diagramme suivant:

DataSource-Proxy

Vous pouvez définir le dataSourcebean qui sera utilisé par Hibernate comme suit:

@Bean
public DataSource dataSource(DataSource actualDataSource) {
    SLF4JQueryLoggingListener loggingListener = new SLF4JQueryLoggingListener();
    loggingListener.setQueryLogEntryCreator(new InlineQueryLogEntryCreator());
    return ProxyDataSourceBuilder
        .create(actualDataSource)
        .name(DATA_SOURCE_PROXY_NAME)
        .listener(loggingListener)
        .build();
}

Notez que le actualDataSourcedoit être DataSourcedéfini par le pool de connexions que vous utilisez dans votre application.

Une fois que vous l'activez datasource-proxy, l'instruction SQl va être enregistrée comme suit:

Name:DATA_SOURCE_PROXY, Time:6, Success:True,
Type:Prepared, Batch:True, QuerySize:1, BatchSize:3,
Query:["insert into post (title, version, id) values (?, ?, ?)"],
Params:[(Post no. 0, 0, 0), (Post no. 1, 0, 1), (Post no. 2, 0, 2)]
Vlad Mihalcea
la source
11

Pour le pilote de serveur MS-SQL (pilote JDBC Microsoft SQL Server).

essayez d'utiliser:

logging.level.com.microsoft.sqlserver.jdbc=debug

dans votre fichier application.properties.

Ma préférence personnelle est de définir:

logging.level.com.microsoft.sqlserver.jdbc=info
logging.level.com.microsoft.sqlserver.jdbc.internals=debug

Vous pouvez consulter ces liens pour référence:

Javier Z.
la source
8

Selon la documentation, c'est:

spring.jpa.show-sql=true # Enable logging of SQL statements.
Max Farsikov
la source
J'ai un problème inverse, le définissant sur faux, et org.hibernate au niveau ERREUR et son impression / création / insertion / sélection toujours en cours d'impression
Kalpesh Soni
5

Réponse acceptée traduite à YAML fonctionne pour moi

logging:
  level:
    org:
      hibernate:
        SQL:
          TRACE
        type:
          descriptor:
            sql:
              BasicBinder:
                TRACE
Robert.Li
la source
3
Vous pouvez également utiliser des propriétés plates dans YAML si vous ne voulez pas imbriquer d'accessoires à usage unique, comme: logging.level.org.hibernate.SQL: TRACE logging.level.org.hibernate.type.descriptor.sql.BasicBinder: TRACE
MarcinJ
4

Nous pouvons utiliser n'importe lequel de ces fichiers dans le fichier application.properties :

spring.jpa.show-sql=true 

example :
//Hibernate: select country0_.id as id1_0_, country0_.name as name2_0_ from country country0_

ou

logging.level.org.hibernate.SQL=debug 

example :
2018-11-23 12:28:02.990 DEBUG 12972 --- [nio-8086-exec-2] org.hibernate.SQL   : select country0_.id as id1_0_, country0_.name as name2_0_ from country country0_
Lova Chittumuri
la source
3

Si vous souhaitez afficher les paramètres réels utilisés pour interroger, vous pouvez utiliser

logging.level.org.hibernate.SQL=DEBUG
logging.level.org.hibernate.type.descriptor.sql=TRACE

Notez ensuite que la valeur réelle du paramètre est affichée comme binding parameter......

   2018-08-07 14:14:36.079 DEBUG 44804 --- [           main] org.hibernate.SQL                        : select employee0_.id as id1_0_, employee0_.department as departme2_0_, employee0_.joining_date as joining_3_0_, employee0_.name as name4_0_ from employee employee0_ where employee0_.joining_date=?
    2018-08-07 14:14:36.079 TRACE 44804 --- [           main] o.h.type.descriptor.sql.BasicBinder      : binding parameter [1] as [TIMESTAMP] - [Tue Aug 07 00:00:00 SGT 2018]
Udara SS Liyanage
la source
3

Connectez-vous à la sortie standard

Ajouter à application.properties

### to enable
spring.jpa.show-sql=true
### to make the printing SQL beautify
spring.jpa.properties.hibernate.format_sql=true

C'est le moyen le plus simple d'imprimer les requêtes SQL, bien qu'il ne consigne pas les paramètres des instructions préparées. Et ce n'est pas recommandé car ce n'est pas le cas du cadre de journalisation optimisé.

Utilisation de la structure de journalisation

Ajouter à application.properties

### logs the SQL queries
logging.level.org.hibernate.SQL=DEBUG
### logs the prepared statement parameters
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE
### to make the printing SQL beautify
spring.jpa.properties.hibernate.format_sql=true

En spécifiant les propriétés ci-dessus, les entrées de journaux seront envoyées à l'appendice de journal configuré tel que log-back ou log4j.

Saveendra Ekanayake
la source
0

Si vous rencontrez des problèmes avec ce paramètre et qu'il semble fonctionner parfois et pas à d'autres moments - vérifiez si les moments où cela ne fonctionne pas sont pendant les tests unitaires.

De nombreuses personnes déclarent des propriétés de temps de test personnalisées via l' @TestPropertySourcesannotation déclarée quelque part dans votre hiérarchie d'héritage de test. Cela remplacera tout ce que vous mettez dans votre application.propertiesou dans d'autres paramètres de propriétés de production afin que les valeurs que vous définissez soient effectivement ignorées au moment du test.

Dépouillé
la source
0

La mise spring.jpa.properties.hibernate.show_sql=trueen application.properties n'a pas toujours aidé.

Vous pouvez essayer d'ajouter properties.put("hibernate.show_sql", "true");aux propriétés de la configuration de la base de données.

public class DbConfig {

    @Primary
    @Bean(name = "entityManagerFactory")
    public LocalContainerEntityManagerFactoryBean
    entityManagerFactory(
            EntityManagerFactoryBuilder builder,
            @Qualifier("dataSource") DataSource dataSource
    ) {
        Map<String, Object> properties = new HashMap();
        properties.put("hibernate.hbm2ddl.auto", "validate");
        properties.put("hibernate.show_sql", "true");

        return builder
                .dataSource(dataSource)
                .packages("com.test.dbsource.domain")
                .persistenceUnit("dbsource").properties(properties)
                .build();
    }
SJX
la source