环境:SpringBoot3.4.0
1. 简介
在Spring Boot应用开发中,监控和记录SQL执行语句对于调试、性能优化以及确保数据访问层的正确性至关重要。无论是使用JDBC直接操作数据库,还是通过JPA或MyBatis等ORM框架,他们都有不同的SQL语句的记录方式。
本文将介绍在Spring Boot中使用JDBC、JPA及MyBatis进行数据库操作时记录执行的SQL语句。这些方法包括配置日志级别以捕获SQL输出、自定义数据源输出SQL语句,以及使用第三方库来增强SQL记录的功能。
2. 实战案例
2.1 JDBC记录SQL
如下数据库操作:
private final JdbcTemplate jdbcTemplate ;
public JdbcService(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
public void query() {
String sql = "select id, name, age from user x where x.id = ?" ;
User user = this.jdbcTemplate.queryForObject(sql, new RowMapper<User>() {
public User mapRow(ResultSet rs, int rowNum) throws SQLException {
return new User(rs.getLong(1), rs.getString(2), rs.getString(3)) ;
}
}, 8) ;
System.err.printf("user = %s\n", user) ;
}
默认情况下,执行上面操作是不会输出任何SQL语句的,我们可以通过如下的配置:
logging:
level:
'[org.springframework.jdbc.core.JdbcTemplate]': debug
图片
如果你还希望输出动态参数,则再添加如下日志配置:
logging:
level:
'[org.springframework.jdbc.core.StatementCreatorUtils]': trace
图片
2.2 JPA记录SQL
如下数据库操作:
private final UserRepository userRepository ;
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
public User findById(Long id) {
return this.userRepository.findById(id).orElse(null) ;
}
最常见的输出执行SQL方式
spring:
jpa:
show-sql: true
properties:
hibernate:
'[format_sql]': true
图片
但是此种方式是直接通过System.out方式进行输出,并且还不会记录预处理语句的参数;不推荐此做法。
使用日志框架记录
在application.yml或properties中进行日志的配置:
logging:
level:
'[org.hibernate.SQL]': debug
'[org.hibernate.orm.jdbc.bind]': trace
org.hibernate.SQL:记录执行的SQL。
org.hibernate.orm.jdbc.bind:记录预处理语句的参数。
图片
2.3 MyBatis记录SQL
如下数据库操作:
@Select("select id, age, name, deleted from user where id = ${id}")
User queryUserById(@Param("id") Long id) ;
注意:${xx}有注入风险?我重写了mybatis处理SQL的一个核心类,不再有任何注入风险。
比较常见的配置日志方式
mybatis:
configuration:
map-underscore-to-camel-case: true
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
如上配置日志输出结果如下:
图片
不仅仅输出的是sql还将数据也输出了,并且这里是通过System.out进行输出的,并且还不管你是否配置的debug级别都会进行输出,下面是源码部分:
图片
使用SLF4j日志实现
mybatis:
configuration:
map-underscore-to-camel-case: true
log-impl: org.apache.ibatis.logging.slf4j.Slf4jImpl
如上配置后并不会输出sql日志,还需要进行如下的配置:
logging:
level:
'[com.pack.mapper]': DEBUG
2.4 万能SQL记录方式
使用拦截器是记录各种SQL查询的最佳方法。在这种方法中,我们可以拦截JDBC调用,对其进行格式化,然后以自定义格式记录SQL查询。
下面介绍一个第三方开源库datasource-proxy,该组件用于拦截SQL查询并记录。
<dependency>
<groupId>com.github.gavlyukovskiy</groupId>
<artifactId>datasource-proxy-spring-boot-starter</artifactId>
<version>1.10.0</version>
</dependency>
日志级别配置如下:
logging:
level:
'[net.ttddyy.dsproxy.listener]': debug
这时候不论你使用JDBC,JPA还是MyBatis都能优雅的记录SQL信息。
图片