介绍几种Spring Boot打印SQL明细包括语句和参数方式

原创 夏壹 夏壹分享 2024年07月18日 08:30

在Spring Boot项目中,经常需要打印SQL语句及其参数,以便于调试和优化数据库操作。

本文将介绍几种在Spring Boot项目中实现SQL日志打印的方法。

  1. 使用MyBatis-Plus配置日志打印

案例背景:
在Spring Boot项目中,如果使用了MyBatis-Plus框架,可以通过简单的配置来实现SQL日志的打印,便于开发和调试。

配置步骤:

  1. 修改application.properties或application.yml文件:
    在配置文件中添加以下配置来开启MyBatis-Plus的SQL日志打印功能。

# application.properties 示例  mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

或者在application.yml中配置:

mybatis-plus:    configuration:      log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

效果展示:
配置完成后,当应用执行数据库操作时,MyBatis-Plus会自动将执行的SQL语句及其参数打印到控制台。例如:

Creating a new SqlSession  SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@xxx] was not registered for synchronization because synchronization is not active  JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@xxx] will not be managed by Spring  ==>  Preparing: SELECT t3.user_id, t3.user_name, t2.role_id, t2.role_name FROM my_user_role_rel t1 LEFT JOIN my_role t2 ON t1.role_id = t2.role_id LEFT JOIN my_user t3 ON t1.user_id = t3.user_id WHERE t1.user_id = ? AND t2.role_id = ?  ==> Parameters: 1(Long), 1(Long)  <==      Columns: user_id, user_name, role_id, role_name  <==        Row: 1, 用户1, 1, 超级管理员  <==        Row: 1, 用户1, 2, 游客  <==      Total: 2  Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@xxx]

优势:

  • 配置简单,无需编写额外代码。

  • 适用于大多数基于MyBatis-Plus的Spring Boot项目。

2. 整合p6spy框架进行SQL日志跟踪

案例背景:
p6spy是一个开源的数据库操作监控工具,可以拦截并记录应用程序发送到数据库的SQL语句及其执行时间等信息。

配置步骤:

  1. 添加p6spy依赖:
    在项目的pom.xml文件中添加p6spy的Maven依赖。

<dependency>      <groupId>p6spy</groupId>      <artifactId>p6spy</artifactId>      <version>最新版本号</version>  </dependency>

修改数据源配置:
application.propertiesapplication.yml文件中修改数据源配置,使用p6spy的Driver。

# application.properties 示例  spring.datasource.url=jdbc:p6spy:mysql://localhost:3306/yourdatabase?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai  spring.datasource.driver-class-name=com.p6spy.engine.spy.P6SpyDriver

配置spy.properties:
src/main/resources目录下创建spy.properties文件,进行p6spy的详细配置,如日志格式、日志级别等。

# spy.properties 示例  appender=com.p6spy.engine.spy.appender.StdoutLogger  logMessageFormat=custom  customLogMessageFormat=%(currentTime)|%(executionTime)|%(category)|%(sql)

效果展示:
配置完成后,p6spy会自动拦截并记录所有数据库操作,将SQL语句及其执行时间等信息打印到控制台或指定的日志文件中。

|2023-04-01 12:34:56|0ms|0|statement|select * from users where id = ?|select * from users where id = 1  |2023-04-01 12:34:56|10ms|0|statement|insert into logs (message, timestamp) values (?, ?)|insert into logs (message, timestamp) values ('User 1 logged in', '2023-04-01T12:34:56Z')  |2023-04-01 12:35:00|2ms|0|statement|update users set status = ? where id = ?|update users set status = 'active' where id = 1

优势:

  • 功能强大,支持详细的SQL日志跟踪。

  • 可配置性强,支持多种日志格式和输出方式

3. 使用MyBatis拦截器实现系统日志记录

MyBatis提供了强大的拦截器功能,允许我们在SQL语句执行的不同阶段插入自定义的逻辑。通过实现MyBatis的Interceptor接口,我们可以轻松地记录SQL语句及其参数。

步骤 1: 创建MyBatis拦截器

首先,我们需要创建一个类来实现Interceptor接口。在这个类中,我们将编写拦截SQL语句的逻辑,并在执行前后记录日志。

import org.apache.ibatis.executor.statement.StatementHandler;  import org.apache.ibatis.plugin.*;    import java.sql.Connection;  import java.util.Properties;    @Intercepts({@Signature(          type = StatementHandler.class,          method = "prepare",          args = {Connection.class, Integer.class}  )})  public class SqlLoggingInterceptor implements Interceptor {        @Override      public Object intercept(Invocation invocation) throws Throwable {          StatementHandler statementHandler = (StatementHandler) Plugin.getTarget(invocation.getTarget());          // 获取SQL语句          String sql = statementHandler.getBoundSql().getSql();          // 获取SQL参数(可能需要根据实际情况进行解析)          Object parameterObject = statementHandler.getBoundSql().getParameterObject();            // 这里可以添加日志记录逻辑          System.out.println("Executing SQL: " + sql);          // 注意:直接打印参数对象可能不是很有用,因为它可能是一个复杂的对象          // 在实际应用中,你可能需要解析这个对象并打印出具体的参数值            // 继续执行原有的逻辑          return invocation.proceed();      }        @Override      public Object plugin(Object target) {          return Plugin.wrap(target, this);      }        @Override      public void setProperties(Properties properties) {          // 可以在这里设置拦截器的属性      }  }
 


复制代码

步骤 2: 配置MyBatis拦截器

接下来,你需要在MyBatis的配置文件(如mybatis-config.xml)或Spring Boot的配置中注册这个拦截器。

对于Spring Boot项目,你通常可以通过配置类来注册MyBatis拦截器:

import org.apache.ibatis.session.SqlSessionFactory;  import org.mybatis.spring.boot.autoconfigure.ConfigurationCustomizer;  import org.springframework.context.annotation.Bean;  import org.springframework.context.annotation.Configuration;    @Configuration  public class MyBatisConfig {        @Bean      public SqlLoggingInterceptor sqlLoggingInterceptor() {          return new SqlLoggingInterceptor();      }        @Bean      public ConfigurationCustomizer mybatisConfigurationCustomizer(SqlLoggingInterceptor sqlLoggingInterceptor) {          return configuration -> configuration.addInterceptor(sqlLoggingInterceptor);      }  }

注意事项

  • 拦截器可能会稍微降低应用程序的性能,因为它在每次数据库操作之前和之后都执行了额外的代码。

  • 在生产环境中,你可能希望关闭详细的SQL日志记录,以避免敏感信息泄露或日志文件过大。

  • 解析复杂的参数对象可能需要编写额外的代码,并且可能会引入错误。确保你的参数解析逻辑是健壮的,并且不会引入新的性能问题。

4. 结合Logback和application.properties

如果你的项目使用了Spring Boot默认的日志框架Logback,并且想要通过application.properties文件结合Logback的配置来打印SQL日志,你可以通过修改logback-spring.xml文件(或logback.xml,取决于你的项目结构)来实现。

但是,通常情况下,对于SQL日志的打印,我们更多地是通过application.propertiesapplication.yml中的日志级别配置来控制,而不是直接在Logback配置文件中指定。不过,为了完整性,这里说明一下Logback配置文件的潜在用途。

logback-spring.xml中,你可以为特定的日志记录器(logger)设置级别,例如:

<logger name="org.hibernate.SQL" level="DEBUG"/>  <logger name="org.hibernate.type.descriptor.sql.BasicBinder" level="TRACE"/>

然而,请注意,在实际项目中,更常见的做法是直接通过application.propertiesapplication.yml中的配置来控制日志级别,因为这样做更加简便且易于管理。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值