我想把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语句?


当前回答

要避免的设置

你不应该使用这个设置:

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数据源,如下图所示:

你可以这样定义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必须是您在应用程序中使用的连接池定义的数据源。

接下来,您需要在日志框架配置文件中将net.ttddyy.dsproxy.listener日志级别设置为调试。例如,如果你正在使用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)]

其他回答

试着在你的属性文件中使用这个:

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

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

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

第二行用于美化SQL语句。

如果你想使用记录器,你可以使用以下几行:

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

第二行用于打印与查询绑定的所有参数。

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

# Show SQL statement
logging.level.org.hibernate.SQL=debug

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

在应用程序中添加spring.jpa.properties.hibernate.show_sql=true。属性并不总是有帮助。

您可以尝试添加properties.put(“hibernate。show_sql”、“真正的”);到数据库配置的属性。

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

要避免的设置

你不应该使用这个设置:

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数据源,如下图所示:

你可以这样定义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必须是您在应用程序中使用的连接池定义的数据源。

接下来,您需要在日志框架配置文件中将net.ttddyy.dsproxy.listener日志级别设置为调试。例如,如果你正在使用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)]