问题描述
我正在使用 spring-data-jpa 构建一个 SpringBoot 应用程序。 我知道如何从这个问题记录所有 sql。
但是如果我只想记录失败的 sql 呢?
1楼
有两种选择:
- 使用参数值配置 sql 日志记录。 禁用 jdbc 批处理并通过休眠方式启用刷新。
- 添加调试 JDBC 驱动程序,例如 p6spy,它们或多或少会完全按照上述说明进行操作。
首先,我们来分析问题,将查询类型拆分为SELECT 和INSERT/UPDATE 查询。
- 默认情况下,您对它们进行SELECT 查询。 因此,当发生错误时,您可以确切地知道哪个查询失败了。
- INSERT/UPDATE 查询,这里事情变得棘手,因为您的刷新将关闭并且您有查询批处理,这意味着首先当您运行查询时它会被延迟。 其次,它与其他不相关的查询打包在一起,第三,Hibernate 可能会对它们重新排序。 所以简短的回答是,如果您单独使用休眠,这对于 INSERT/UPDATE 是不可行的。
您的问题的解决方案基本上需要做两件事: 1. 它应该记录查询及其参数值。 这可以通过以下方式完成:
# logs the SQL statements
log4j.logger.org.hibernate.SQL=debug
# Logs the JDBC parameters passed to a query
log4j.logger.org.hibernate.type=trace
2. 解决方案需要关闭批处理查询,否则,你会得到一堆SQL,但你不知道究竟哪个SQL是有问题的。
hibernate.jdbc.batch_size=1
不确定这是否足以完全禁用批处理,但您需要找出答案。
或者,您可以使用专为 DEBUG 设计的 jdbc 驱动程序。 这将是 p6spy 驱动程序,它可以选择刷新每个 SQL 语句,这正是您想要的。
这里需要设置autoflush=true
配置参数,以确保每条 sql 语句都立即刷新到数据库中。
2楼
这为您提供了多个日志条目。
就我而言,这是不受欢迎的。
这是我的解决方案:
- 依赖 net.ttddyy:datasource-proxy:1.6
- 在 Spring 配置中包装数据源
@Bean
public DataSource dataSource() {
return ProxyDataSourceBuilder.create(originalDatasource())
.logQueryBySlf4j(FLF4JLogLevel.DEBUG).build();
}
- 编写您自己的 LogAppender - 在这里您可以过滤日志事件,因此您可以过滤 ie 仅插入或执行失败
public class SQLAppender extends AppenderBase
[...]
@Override
protected void append(ILoggingEvent eventObject) {
[...]
}
- 配置 logback.xml
<appender name="mySQLAppender" class="com.my.SQLAppender" > </appender> <logger name="net.ttddyy.dsproxy.listener.logging.SLF4JQueryLoggingListener" level="DEBUG"\\> <appender-ref ref="mySQLAppender"/> </logger>