【问题标题】:How to log SQL statements in Spring Boot?如何在 Spring Boot 中记录 SQL 语句?
【发布时间】: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语句?

【问题讨论】:

标签: java spring hibernate spring-boot logging


【解决方案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 属性,所以它不起作用。下面stackoverflow.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
                          

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

                          【讨论】:

                            【解决方案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的人呢?
                            猜你喜欢
                            • 1970-01-01
                            • 2021-01-11
                            • 2018-03-21
                            • 2011-02-03
                            • 1970-01-01
                            • 2018-09-04
                            • 2019-04-01
                            • 2022-09-26
                            相关资源
                            最近更新 更多