如何在Spring Boot中记录SQL语句?


342

我想将SQL语句记录在文件中。
我在以下属性application.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

当我运行我的应用程序时

cmd>mvn spring-boot:run

我可以在控制台中看到sql语句,但它们未出现在文件app.log中。该文件仅包含来自spring的基本日志。

如何查看日志文件中的sql语句?

Answers:


458

尝试在属性文件中使用它:

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

74
如果您也想记录值:logging.level.org.hibernate.type=TRACE
elysch

2
但这仅记录很少的绑定值。如何记录来自标准API的值?如果使用“规范”,那么使用CriteriaBuilder创建的绑定参数将没有输出。
乔什(Josh)2013年

203

这也适用于stdout:

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

要记录值:

logging.level.org.hibernate.type=trace

只需将其添加到application.properties


11
如果您也想记录值:spring.jpa.properties.hibernate.type=trace
elysch

1
这不会写入日志文件,而是写入STDOUT
Muhammad Hewedy

4
我仍然只看到?参数而不是参数。该解决方案是否应该向我展示?
Adeynack '18

1
spring.jpa.properties.hibernate.type = trace不会影响我的日志文件;(
gstackoverflow

1
“ type = trace”不是spring属性,因此不起作用。在stackoverflow.com/a/41594913/5107365下方给出的解决方案是正确的选择。
拉吉

96

这对我有用(YAML):

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

18

请用:

logging.level.org.hibernate.SQL=DEBUG
logging.level.org.hibernate.type=TRACE
spring.jpa.show-sql=true

4
logging.level.org.hibernate.SQL=DEBUG使它对我有用,而其他答案却不见了。谢谢!
维克(Vic)

18

如果您有logback-spring.xml或类似的内容,请向其中添加以下代码

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

为我工作。

同样要获取绑定变量:

<logger name="org.hibernate.type.descriptor.sql" level="trace">
    <appender-ref ref="file" />
</logger>

1
使用Spring Boot必须使用<appender-ref ref="FILE" />
Ortomala Lokni,

appender ref是您在logback xml中定义的appender的名称。它只是一个变量
Raja Anbazhagan

17

由于这是一个非常常见的问题,因此我写了 这篇文章,此答案基于该文章

避免设置

您不应使用此设置:

spring.jpa.show-sql=true 

问题show-sql在于,SQL语句是在控制台中打印的,因此无法像通常使用Logging框架那样过滤它们。

使用休眠日志

在日志配置文件中,如果添加以下记录器:

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

然后,在PreparedStatement创建JDBC时,Hibernate将打印SQL语句。这就是为什么将使用参数占位符记录该语句的原因:

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

如果要记录绑定参数值,只需添加以下记录器:

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

设置BasicBinder记录器后,您还将看到绑定参数值也已记录:

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]

使用数据源代理

数据源代理允许您代理实际的JDBC DataSource,通过如下图所示:

数据源代理

您可以如下定义dataSourceHibernate将使用的bean:

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

注意,actualDataSource必须DataSource由您在应用程序中使用的连接池定义。

一旦启用datasource-proxy,SQl语句将被记录如下:

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)]

11

对于MS-SQL服务器驱动程序(Microsoft SQL Server JDBC驱动程序)。

尝试使用:

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

在您的application.properties文件中。

我个人的喜好是设置:

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

您可以查看以下链接以供参考:



5

已翻译的YAML可接受答案对我有用

logging:
  level:
    org:
      hibernate:
        SQL:
          TRACE
        type:
          descriptor:
            sql:
              BasicBinder:
                TRACE

3
如果您不想嵌套一次性使用的道具,也可以在YAML中使用平面属性,例如: logging.level.org.hibernate.SQL: TRACE logging.level.org.hibernate.type.descriptor.sql.BasicBinder: TRACE
MarcinJ

4

我们可以在application.properties文件中使用以下任意一项:

spring.jpa.show-sql=true 

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

要么

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_

3

如果要查看用于查询的实际参数,可以使用

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

然后注意实际参数值显示为 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]

3

登录到标准输出

添加 application.properties

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

这是打印SQL查询的最简单方法,尽管它不会记录准备好的语句的参数。不建议使用它,因为它不像优化的日志记录框架那样。

使用日志记录框架

添加 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

通过指定以上属性,日志条目将发送到已配置的日志附加程序,例如log-back或log4j。


0

如果您在使用此设置时遇到麻烦,并且似乎有时可以使用,而在其他时间则无法使用-请考虑在单元测试期间不起作用的时间。

许多人通过@TestPropertySources在测试继承层次结构中某处声明的注释来声明自定义测试时间属性。这将覆盖您在application.properties生产属性设置或其他生产属性设置中放置的所有内容,因此您设置的那些值在测试时将被有效忽略。


0

spring.jpa.properties.hibernate.show_sql=true在application.properties并不总是帮助。

您可以尝试添加properties.put("hibernate.show_sql", "true");到数据库配置的属性。

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();
    }
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.