Bagaimana cara mencatat pernyataan SQL di Spring Boot?

342

Saya ingin mencatat pernyataan SQL dalam file.
Saya memiliki properti berikut diapplication.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

Ketika saya menjalankan aplikasi saya

cmd>mvn spring-boot:run

Saya bisa melihat pernyataan sql di konsol tetapi tidak muncul di file app.log. File hanya berisi log dasar dari pegas.

Apa yang harus saya lakukan untuk melihat pernyataan sql dalam file log?

Oleg Pavliv
sumber

Jawaban:

458

coba gunakan ini di file properti Anda:

logging.level.org.hibernate.SQL=DEBUG
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE
Paul Woods
sumber
74
Jika Anda ingin mencatat nilai juga:logging.level.org.hibernate.type=TRACE
elysch
2
Tapi ini hanya mencatat beberapa nilai mengikat. Bagaimana saya bisa mencatat nilai dari API kriteria? Jika saya menggunakan Spesifikasi, saya tidak mendapatkan output untuk parameter terikat yang dibuat dengan CriteriaBuilder.
Josh
204

Ini juga berfungsi untuk stdout:

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

Untuk mencatat nilai:

logging.level.org.hibernate.type=trace

Cukup tambahkan ini ke application.properties.

v.ladynev
sumber
11
Jika Anda ingin mencatat nilai juga:spring.jpa.properties.hibernate.type=trace
elysch
1
Ini tidak menulis ke file log, ini menulis ke STDOUT
Muhammad Hewedy
4
Saya masih melihat ?parameter saja. Apakah solusi itu seharusnya menunjukkannya kepada saya?
Adeynack
1
spring.jpa.properties.hibernate.type = jejak tidak memengaruhi file log saya; (
gstackoverflow
1
"Type = trace" bukan properti pegas, jadi itu tidak berfungsi. Solusi yang diberikan di bawah ini stackoverflow.com/a/41594913/5107365 adalah solusi yang tepat untuk itu.
Raj
97

Ini bekerja untuk saya (YAML):

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

Mohon gunakan:

logging.level.org.hibernate.SQL=DEBUG
logging.level.org.hibernate.type=TRACE
spring.jpa.show-sql=true
rahulnikhare
sumber
4
logging.level.org.hibernate.SQL=DEBUGmembuatnya bekerja untuk saya dan tidak ada jawaban lain. Terima kasih!
Vic
18

jika Anda memiliki logback-spring.xml atau sesuatu seperti itu, tambahkan kode berikut untuk itu

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

bekerja untukku.

Untuk mendapatkan variabel ikat juga:

<logger name="org.hibernate.type.descriptor.sql" level="trace">
    <appender-ref ref="file" />
</logger>
Edye Chan
sumber
1
Dengan Spring Boot, Anda harus menggunakan<appender-ref ref="FILE" />
Ortomala Lokni
appender ref adalah nama appender yang telah Anda tentukan di xml logback. Ini hanya variabel
Raja Anbazhagan
17

Karena ini adalah pertanyaan yang sangat umum, saya menulis artikel ini , yang menjadi dasar jawaban ini.

Pengaturan yang harus dihindari

Anda seharusnya tidak menggunakan pengaturan ini:

spring.jpa.show-sql=true 

Masalahnya show-sqladalah bahwa pernyataan SQL dicetak di konsol, jadi tidak ada cara untuk memfilternya, seperti yang biasanya Anda lakukan dengan kerangka Logging.

Menggunakan Hibernate logging

Di file konfigurasi log Anda, jika Anda menambahkan logger berikut:

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

Kemudian, Hibernate akan mencetak pernyataan SQL ketika JDBC PreparedStatementdibuat. Itu sebabnya pernyataan akan dicatat menggunakan penampung parameter:

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

Jika Anda ingin mencatat nilai parameter bind, tambahkan juga logger berikut:

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

Setelah Anda mengatur BasicBinderlogger, Anda akan melihat bahwa nilai parameter bind juga dicatat:

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]

Menggunakan sumber data-proxy

Data -proxy-proksi memungkinkan Anda untuk mem-proxy JDBC yang sebenarnya DataSource, seperti yang diilustrasikan oleh diagram berikut:

DataSource-Proxy

Anda bisa mendefinisikan dataSourcekacang yang akan digunakan oleh Hibernate sebagai berikut:

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

Perhatikan bahwa actualDataSourceharus DataSourceditentukan oleh kumpulan koneksi yang Anda gunakan dalam aplikasi Anda.

Setelah Anda mengaktifkan datasource-proxy, pernyataan SQl akan dicatat sebagai berikut:

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
sumber
11

Untuk pengandar server MS-SQL (Microsoft SQL Server JDBC Driver).

coba gunakan:

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

dalam file application.properties Anda.

Preferensi pribadi saya adalah untuk mengatur:

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

Anda dapat melihat tautan ini untuk referensi:

Javier Z.
sumber
8

Menurut dokumentasi itu adalah:

spring.jpa.show-sql=true # Enable logging of SQL statements.
Max Farsikov
sumber
Saya memiliki masalah terbalik, mengatur ini ke false, dan org.hibernate ke level ERROR dan masih mencetak drop / create / insert / select
Kalpesh Soni
5

Jawaban yang diterima yang diterjemahkan ke YAML bekerja untuk saya

logging:
  level:
    org:
      hibernate:
        SQL:
          TRACE
        type:
          descriptor:
            sql:
              BasicBinder:
                TRACE
Robert.Li
sumber
3
Anda juga dapat menggunakan properti flat di YAML jika Anda tidak ingin membuat sarang untuk alat peraga sekali pakai, seperti: logging.level.org.hibernate.SQL: TRACE logging.level.org.hibernate.type.descriptor.sql.BasicBinder: TRACE
MarcinJ
4

Kita dapat menggunakan salah satu dari ini di file application.properties :

spring.jpa.show-sql=true 

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

atau

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
sumber
3

Jika Anda ingin melihat parameter aktual yang digunakan untuk kueri, Anda dapat menggunakan

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

Kemudian perhatikan bahwa nilai parameter aktual ditampilkan sebagai 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
sumber
3

Masuk ke output standar

Tambahkan application.properties

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

Ini cara termudah untuk mencetak kueri SQL meskipun tidak mencatat parameter pernyataan yang disiapkan. Dan ini tidak direkomendasikan karena tidak seperti kerangka logging yang dioptimalkan.

Menggunakan Logging Framework

Tambahkan 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

Dengan menentukan properti di atas, entri log akan dikirim ke appender log yang dikonfigurasi seperti log-back atau log4j.

Saveendra Ekanayake
sumber
0

Jika Anda mengalami masalah dengan pengaturan ini dan sepertinya berfungsi kadang-kadang dan tidak di waktu lain - pertimbangkan jika waktu di mana itu tidak berhasil adalah selama unit test.

Banyak orang menyatakan properti waktu pengujian khusus melalui @TestPropertySourcesanotasi yang dinyatakan di suatu tempat di hierarki warisan pengujian Anda. Ini akan mengesampingkan apa pun yang Anda masukkan ke application.propertiespengaturan properti produksi Anda atau lainnya sehingga nilai-nilai yang Anda setel secara efektif diabaikan pada saat pengujian.

Dicukur
sumber
0

Menempatkan spring.jpa.properties.hibernate.show_sql=truedi application.properties tidak selalu membantu.

Anda dapat mencoba menambahkan properties.put("hibernate.show_sql", "true");properti konfigurasi database.

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
sumber