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

Posted

技术标签:

【中文标题】如何在 Spring Boot 中记录 SQL 语句?【英文标题】:How to log SQL statements in Spring Boot? 【发布时间】:2018-06-19 06:37:16 【问题描述】:

我想在文件中记录 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语句?

【问题讨论】:

按照baeldung.com/sql-logging-spring-boot上的说明进行操作 【参考方案1】:

您可以简单地在 application.properties 中为 stdout SQL 查询添加以下行:

spring.jpa.properties.hibernate.show_sql=true

【讨论】:

【参考方案2】:

在属性中添加这些。引用Hibernate Show SQL:

#show sql statement
logging.level.org.hibernate.SQL=debug

#show sql values
logging.level.org.hibernate.type.descriptor.sql=trace

【讨论】:

【参考方案3】:

基本方法是在您的application.properties 中添加以下行。这将使 Spring Boot 能够记录所有执行的 SQL 查询:

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

第 2 行用于美化 SQL 语句。

如果要使用记录器,可以使用以下行:

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

第二行用于打印与查询绑定的所有参数。 希望这对你有用。 如果您还有任何疑问,请告诉我!

【讨论】:

【参考方案4】:

如果您有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>

【讨论】:

使用 Spring Boot 你必须使用&lt;appender-ref ref="FILE" /&gt; appender ref 是您在 logback xml 中定义的 appender 的名称。它只是一个变量【参考方案5】:

在我的 yaml 中:

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

Spring boot 版本:2.3.5.RELEASE

【讨论】:

【参考方案6】:

要避免的设置

你不应该使用这个设置:

spring.jpa.show-sql=true 

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

使用 Hibernate 日志记录

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

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

然后,Hibernate 将在创建 JDBC PreparedStatement 时打印 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]

使用数据源代理

datasource-proxy OSS 框架允许您代理实际的 JDBC DataSource,如下图所示:

您可以按如下方式定义 Hibernate 将使用的 dataSource 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 必须是您在应用程序中使用的[连接池][2] 定义的DataSource

接下来,您需要在日志框架配置文件中将net.ttddyy.dsproxy.listener 日志级别设置为debug。例如,如果您使用 Logback,则可以添加以下记录器:

<logger name="net.ttddyy.dsproxy.listener" level="debug"/>

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

【讨论】:

在这里启用datasource-proxy 到底是什么意思?是另一种配置吗?除了使用正确的数据源创建 bean 之外,是否还有其他需要配置的东西?此时我们是否还需要在 log4j.properties 中配置一些东西? 我更新了答案来回答你的问题。 完美答案!谢谢 不行,Hibernate怎么知道要使用这个bean? 解释得很好。【参考方案7】:

在文件 application.properties 中使用此代码:

#Enable logging for config troubeshooting
logging.level.org.hibernate.SQL=DEBUG
logging.level.com.zaxxer.hikari.HikariConfig=DEBUG
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE

【讨论】:

【参考方案8】:

你只需要设置 spring.jpa.show-sql=true 在 application.properties 例如你可以引用这个https://github.com/007anwar/ConfigServerRepo/blob/master/application.yaml

【讨论】:

【参考方案9】:

这也适用于标准输出:

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

【讨论】:

如果你也想记录值:spring.jpa.properties.hibernate.type=trace 这不会写入日志文件,而是写入 STDOUT 我仍然只看到? 而不是参数。该解决方案应该向我展示吗? spring.jpa.properties.hibernate.type=trace 不会影响我的日志文件;( "type=trace" 不是 spring 属性,所以它不起作用。下面***.com/a/41594913/5107365 给出的解决方案是正确的。【参考方案10】:

登录标准输出

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

【讨论】:

【参考方案11】:

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

【讨论】:

【参考方案12】:

如果您在使用此设置时遇到问题,并且它似乎有时有效,但有时无效 - 请考虑它是否无效的时间是在单元测试期间。

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

【讨论】:

【参考方案13】:

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

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

【讨论】:

如果您不想嵌套一次性使用的道具,也可以在 YAML 中使用平面属性,例如:logging.level.org.hibernate.SQL: TRACElogging.level.org.hibernate.type.descriptor.sql.BasicBinder: TRACE【参考方案14】:

我们可以使用其中任何一种 在 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_

【讨论】:

【参考方案15】:

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

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]

【讨论】:

【参考方案16】:

请使用:

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

【讨论】:

logging.level.org.hibernate.SQL=DEBUG 使它对我有用,并且缺少其他答案。谢谢!【参考方案17】:

根据documentation是:

spring.jpa.show-sql=true # Enable logging of SQL statements.

【讨论】:

我遇到了反向问题,将其设置为 false,并将 org.hibernate 设置为 ERROR 级别,并且仍在打印 drop/create/insert/select【参考方案18】:

这对我有用(YAML):

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

【讨论】:

【参考方案19】:

用于 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

您可以查看这些链接以供参考:

https://msdn.microsoft.com/en-us/library/ms378517(v=sql.110).aspx https://docs.spring.io/spring-boot/docs/current/reference/html/howto-logging.html

【讨论】:

【参考方案20】:

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

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

【讨论】:

如果你也想记录值:logging.level.org.hibernate.type=TRACE 但这只记录很少的绑定值。如何从标准 API 记录值?如果我使用规范,我不会得到使用 CriteriaBuilder 创建的绑定参数的输出。 那些使用EclipseLink而不是Hibernate的人呢?

以上是关于如何在 Spring Boot 中记录 SQL 语句?的主要内容,如果未能解决你的问题,请参考以下文章

8.如何统一引入Spring Boot的版本?

使用 Spring Boot 记录 Flyway sql

spring boot 打印myabtis sql语句

如何在 Spring Boot 中查看模式 sql (DDL)?

如何在spring boot和hibernate中计算特定id的记录

如何在spring boot中使用hql只获取一条记录