Jak rejestrować instrukcje SQL w Spring Boot?

342

Chcę rejestrować instrukcje SQL w pliku.
Mam następujące właściwości wapplication.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

Kiedy uruchamiam moją aplikację

cmd>mvn spring-boot:run

Widzę instrukcje sql w konsoli, ale nie pojawiają się one w pliku app.log. Plik zawiera tylko podstawowe dzienniki z wiosny.

Co powinienem zrobić, aby wyświetlić instrukcje SQL w pliku dziennika?

Oleg Pawliw
źródło

Odpowiedzi:

458

spróbuj użyć tego w pliku właściwości:

logging.level.org.hibernate.SQL=DEBUG
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE
Paul Woods
źródło
74
Jeśli chcesz także rejestrować wartości:logging.level.org.hibernate.type=TRACE
elysch
2
Ale rejestruje to tylko kilka wartości wiązania. Jak mogę rejestrować wartości z interfejsu API kryteriów? Jeśli użyję specyfikacji, nie otrzymam danych wyjściowych dla powiązanych parametrów utworzonych za pomocą CriteriaBuilder.
Josh
204

Działa to również na standardowe wyjście:

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

Aby zarejestrować wartości:

logging.level.org.hibernate.type=trace

Po prostu dodaj to do application.properties.

v.ladynev
źródło
11
Jeśli chcesz także rejestrować wartości:spring.jpa.properties.hibernate.type=trace
elysch
1
To nie zapisuje do pliku dziennika, to zapisuje do STDOUT
Muhammad Hewedy
4
Nadal widzę tylko ?zamiast parametrów. Czy to rozwiązanie miało mi je pokazać?
Adeynack,
1
spring.jpa.properties.hibernate.type = trace nie wpływa na mój plik dziennika; (
gstackoverflow
1
„Typ = ślad” nie jest właściwością wiosny, więc nie działa. Rozwiązanie podane poniżej stackoverflow.com/a/41594913/5107365 jest do tego odpowiednie.
Raj
97

To działa dla mnie (YAML):

spring:
  jpa:
    properties:
      hibernate:
        show_sql: true
        format_sql: true
logging:
  level:
    org:
      hibernate:
        type: trace
Michel
źródło
18

Proszę użyć:

logging.level.org.hibernate.SQL=DEBUG
logging.level.org.hibernate.type=TRACE
spring.jpa.show-sql=true
rahulnikhare
źródło
4
logging.level.org.hibernate.SQL=DEBUGsprawił, że zadziałało dla mnie i brakowało innych odpowiedzi. Dzięki!
Vic
18

jeśli masz plik logback-spring.xml lub coś takiego, dodaj do niego następujący kod

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

pracuje dla mnie.

Aby uzyskać również zmienne powiązania:

<logger name="org.hibernate.type.descriptor.sql" level="trace">
    <appender-ref ref="file" />
</logger>
Edye Chan
źródło
1
W Spring Boot musisz użyć<appender-ref ref="FILE" />
Ortomala Lokni
appender ref to nazwa programu dołączającego zdefiniowanego w pliku XML logback. To tylko zmienna
Raja Anbazhagan
17

Ponieważ jest to bardzo częste pytanie, napisałem ten artykuł , na którym opiera się ta odpowiedź.

Ustawienia, których należy unikać

Nie należy używać tego ustawienia:

spring.jpa.show-sql=true 

Problem show-sqlpolega na tym, że instrukcje SQL są drukowane w konsoli, więc nie ma możliwości ich filtrowania, jak to zwykle bywa ze strukturą rejestrowania.

Korzystanie z rejestrowania hibernacji

Jeśli dodasz następujący rejestrator w pliku konfiguracyjnym dziennika:

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

Następnie Hibernacja wydrukuje instrukcje SQL podczas tworzenia JDBC PreparedStatement. Dlatego instrukcja będzie rejestrowana przy użyciu symboli zastępczych parametrów:

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

Jeśli chcesz rejestrować wartości parametrów wiązania, dodaj również następujący rejestrator:

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

Po ustawieniu BasicBinderrejestratora zobaczysz, że rejestrowane są również wartości parametrów wiązania:

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]

Korzystanie z źródła danych proxy

Źródło danych proxy pozwala na proxy rzeczywistego JDBC DataSource, jak pokazano na poniższym diagramie:

DataSource-Proxy

Możesz zdefiniować dataSourcefasolę, która będzie używana przez Hibernację w następujący sposób:

@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();
}

Zauważ, że actualDataSourcemusi to być DataSourcezdefiniowany przez pulę połączeń, której używasz w swojej aplikacji.

Po włączeniu datasource-proxyinstrukcja SQl będzie rejestrowana w następujący sposób:

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
źródło
11

Dla sterownika serwera MS-SQL (sterownik JDBC Microsoft SQL Server).

spróbuj użyć:

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

w pliku application.properties.

Moją osobistą preferencją jest ustawienie:

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

Możesz spojrzeć na te linki w celach informacyjnych:

Javier Z.
źródło
8

Według dokumentacji jest to:

spring.jpa.show-sql=true # Enable logging of SQL statements.
Max Farsikov
źródło
Mam odwrotny problem, ustawiam to na false, a org.hibernate na poziom ERROR i nadal drukuje drop / create / insert / select
Kalpesh Soni
5

Przetłumaczona zaakceptowana odpowiedź na YAML działa dla mnie

logging:
  level:
    org:
      hibernate:
        SQL:
          TRACE
        type:
          descriptor:
            sql:
              BasicBinder:
                TRACE
Robert.Li
źródło
3
Możesz także użyć właściwości płaskich w YAML, jeśli nie chcesz zagnieżdżać rekwizytów do jednorazowego użytku, takich jak: logging.level.org.hibernate.SQL: TRACE logging.level.org.hibernate.type.descriptor.sql.BasicBinder: TRACE
MarcinJ
4

Możemy użyć dowolnego z nich w pliku application.properties :

spring.jpa.show-sql=true 

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

lub

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
źródło
3

Jeśli chcesz wyświetlić rzeczywiste parametry użyte do zapytania, możesz użyć

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

Następnie zauważ, że rzeczywista wartość parametru jest pokazana jako 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
źródło
3

Zaloguj się do standardowego wyjścia

Dodać do application.properties

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

Jest to najprostszy sposób na wydrukowanie zapytań SQL, chociaż nie rejestruje parametrów przygotowanych instrukcji. Nie jest to zalecane, ponieważ nie jest to zoptymalizowane środowisko rejestrowania.

Korzystanie ze środowiska rejestrowania

Dodać do 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

Określając powyższe właściwości, wpisy w dziennikach będą wysyłane do skonfigurowanego modułu dołączającego dzienniki, takiego jak log-back lub log4j.

Saveendra Ekanayake
źródło
0

Jeśli masz problemy z tym ustawieniem i wydaje się, że działa ono czasami, a nie innym razem - zastanów się, czy czasy, w których nie działa, występują podczas testów jednostkowych.

Wiele osób deklaruje niestandardowe właściwości czasu testu za pomocą @TestPropertySourcesadnotacji zadeklarowanej gdzieś w hierarchii dziedziczenia testu. Spowoduje to zastąpienie wszystkiego, co wprowadzisz w ustawieniach application.propertiesprodukcyjnych lub innych właściwościach produkcyjnych, dzięki czemu te wartości, które ustawiasz, są skutecznie ignorowane podczas testowania.

Wystrzyżony
źródło
0

Wstawienie spring.jpa.properties.hibernate.show_sql=trueapplication.properties nie zawsze pomagało.

Możesz spróbować dodać properties.put("hibernate.show_sql", "true");do właściwości konfiguracji bazy danych.

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
źródło