Spring Boot中記錄JDBC、JPA及MyBatis執(zhí)行SQL及參數(shù)的正確姿勢
環(huán)境:SpringBoot3.4.0
1. 簡介
在Spring Boot應(yīng)用開發(fā)中,監(jiān)控和記錄SQL執(zhí)行語句對(duì)于調(diào)試、性能優(yōu)化以及確保數(shù)據(jù)訪問層的正確性至關(guān)重要。無論是使用JDBC直接操作數(shù)據(jù)庫,還是通過JPA或MyBatis等ORM框架,他們都有不同的SQL語句的記錄方式。
本文將介紹在Spring Boot中使用JDBC、JPA及MyBatis進(jìn)行數(shù)據(jù)庫操作時(shí)記錄執(zhí)行的SQL語句。這些方法包括配置日志級(jí)別以捕獲SQL輸出、自定義數(shù)據(jù)源輸出SQL語句,以及使用第三方庫來增強(qiáng)SQL記錄的功能。
2. 實(shí)戰(zhàn)案例
2.1 JDBC記錄SQL
如下數(shù)據(jù)庫操作:
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) ;
}默認(rèn)情況下,執(zhí)行上面操作是不會(huì)輸出任何SQL語句的,我們可以通過如下的配置:
logging:
level:
'[org.springframework.jdbc.core.JdbcTemplate]': debug
圖片
如果你還希望輸出動(dòng)態(tài)參數(shù),則再添加如下日志配置:
logging:
level:
'[org.springframework.jdbc.core.StatementCreatorUtils]': trace
圖片
2.2 JPA記錄SQL
如下數(shù)據(jù)庫操作:
private final UserRepository userRepository ;
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
public User findById(Long id) {
return this.userRepository.findById(id).orElse(null) ;
}最常見的輸出執(zhí)行SQL方式
spring:
jpa:
show-sql: true
properties:
hibernate:
'[format_sql]': true
圖片
但是此種方式是直接通過System.out方式進(jìn)行輸出,并且還不會(huì)記錄預(yù)處理語句的參數(shù);不推薦此做法。
使用日志框架記錄
在application.yml或properties中進(jìn)行日志的配置:
logging:
level:
'[org.hibernate.SQL]': debug
'[org.hibernate.orm.jdbc.bind]': traceorg.hibernate.SQL:記錄執(zhí)行的SQL。
org.hibernate.orm.jdbc.bind:記錄預(yù)處理語句的參數(shù)。
圖片
2.3 MyBatis記錄SQL
如下數(shù)據(jù)庫操作:
@Select("select id, age, name, deleted from user where id = ${id}")
User queryUserById(@Param("id") Long id) ;注意:${xx}有注入風(fēng)險(xiǎn)?我重寫了mybatis處理SQL的一個(gè)核心類,不再有任何注入風(fēng)險(xiǎn)。
比較常見的配置日志方式
mybatis:
configuration:
map-underscore-to-camel-case: true
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl如上配置日志輸出結(jié)果如下:
圖片
不僅僅輸出的是sql還將數(shù)據(jù)也輸出了,并且這里是通過System.out進(jìn)行輸出的,并且還不管你是否配置的debug級(jí)別都會(huì)進(jìn)行輸出,下面是源碼部分:
圖片
使用SLF4j日志實(shí)現(xiàn)
mybatis:
configuration:
map-underscore-to-camel-case: true
log-impl: org.apache.ibatis.logging.slf4j.Slf4jImpl如上配置后并不會(huì)輸出sql日志,還需要進(jìn)行如下的配置:
logging:
level:
'[com.pack.mapper]': DEBUG
2.4 萬能SQL記錄方式
使用攔截器是記錄各種SQL查詢的最佳方法。在這種方法中,我們可以攔截JDBC調(diào)用,對(duì)其進(jìn)行格式化,然后以自定義格式記錄SQL查詢。
下面介紹一個(gè)第三方開源庫datasource-proxy,該組件用于攔截SQL查詢并記錄。
<dependency>
<groupId>com.github.gavlyukovskiy</groupId>
<artifactId>datasource-proxy-spring-boot-starter</artifactId>
<version>1.10.0</version>
</dependency>日志級(jí)別配置如下:
logging:
level:
'[net.ttddyy.dsproxy.listener]': debug這時(shí)候不論你使用JDBC,JPA還是MyBatis都能優(yōu)雅的記錄SQL信息。
圖片































