MyBatis-Plus輸出完整SQL(帶參數(shù))的三種方案
為什么 MyBatis Plus 默認(rèn) SQL 日志沒有參數(shù)?
當(dāng)你使用 mybatis-plus 時,可能會遇到這樣的情況:
Preparing: SELECT id, name, `desc` FROM author WHERE name = ? Parameters: 劉禹錫(String)
這導(dǎo)致 SQL 不能直接執(zhí)行,調(diào)試也不方便。那么,如何打印完整 SQL(帶參數(shù))呢?本篇文章將介紹 3 種實(shí)現(xiàn)方式,并對比它們的優(yōu)缺點(diǎn)。
方案 1:使用 SqlLogInterceptor(推薦)
從 MyBatis Plus 3.5.3 版本 開始,官方提供了 SqlLogInterceptor,可以自動替換 SQL 語句中的 ? 為實(shí)際參數(shù)。
配置方式:
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.SqlLogInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MyBatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new SqlLogInterceptor()); // ? 讓 SQL 帶參數(shù)
return interceptor;
}
}
效果:
Executing SQL: SELECT id, name, `desc` FROM author WHERE name = '劉禹錫'
優(yōu)點(diǎn):
- 官方支持,無侵入,簡單易用
- 低性能開銷,僅影響日志輸出
- 適用于 MyBatis Plus
缺點(diǎn):
- 只適用于 MyBatis Plus(普通 MyBatis 需要用方案 2)
方案 2:自定義 MyBatis Interceptor
如果你使用的是 原生 MyBatis,或者想要更靈活的日志格式,可以 自定義 Interceptor。
編寫 Interceptor:
@Intercepts({
@Signature(type = Executor.class, method = "query", args = {
MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class}),
@Signature(type = Executor.class, method = "update", args = {
MappedStatement.class, Object.class})
})
@Slf4j
public class SqlInterceptor implements Interceptor {
@Override
public Object intercept(Invocation invocation) throws Throwable {
long startTime = System.currentTimeMillis();
Object proceed = invocation.proceed();
long endTime = System.currentTimeMillis();
String sql = generateSql(invocation);
log.info("\n 執(zhí)行SQL耗時:{}ms \n 執(zhí)行SQL:{}", endTime - startTime, sql);
return proceed;
}
private static String generateSql(Invocation invocation) {
MappedStatement statement = (MappedStatement) invocation.getArgs()[0];
Object parameter = invocation.getArgs().length > 1 ? invocation.getArgs()[1] : null;
BoundSql boundSql = statement.getBoundSql(parameter);
String sql = boundSql.getSql().replaceAll("[\\s]+", " ");
for (ParameterMapping param : boundSql.getParameterMappings()) {
Object value = boundSql.getAdditionalParameter(param.getProperty());
sql = sql.replaceFirst("\\?", Matcher.quoteReplacement(getParameterValue(value)));
}
return sql;
}
private static String getParameterValue(Object object) {
return object instanceof String ? "'" + object + "'" : String.valueOf(object);
}
@Override
public Object plugin(Object target) {
return Plugin.wrap(target, this);
}
}
優(yōu)點(diǎn):
- 適用于 原生 MyBatis 和 MyBatis Plus
- 可自定義日志格式,控制輸出內(nèi)容
缺點(diǎn):
- 需要手動編寫,稍微復(fù)雜一點(diǎn)
- 性能開銷略大(需要解析 SQL 并替換參數(shù))
方案 3:開啟 MyBatis 日志(手動拼接 SQL)
如果只是 臨時調(diào)試,可以在 application.yml 配置 MyBatis 日志:
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
然后,手動拼接 SQL 進(jìn)行調(diào)試。
優(yōu)點(diǎn):
- 無代碼改動,適合臨時調(diào)試
缺點(diǎn):
- 仍然是
Preparing: xxx和Parameters: xxx的分離格式 - 不能直接復(fù)制執(zhí)行
最佳方案對比與選擇
| 方案 | 適用場景 | 侵入性 | 性能開銷 | 適用框架 |
|---|---|---|---|---|
| SqlLogInterceptor | MyBatis Plus | 無 | 低 | MyBatis Plus |
| 自定義 Interceptor | 需要特殊格式 | 中等 | 中 | MyBatis & MyBatis Plus |
| MyBatis 日志 | 臨時調(diào)試 | 無 | 低 | MyBatis & MyBatis Plus |
結(jié)論:哪種方式適合你?
- 推薦:使用
SqlLogInterceptor,簡單、無侵入,適用于 MyBatis Plus。 - 進(jìn)階:自定義
Interceptor,適用于 MyBatis,可自定義日志格式。 - 臨時調(diào)試:開啟 MyBatis 日志,但不自動替換
?。
到此這篇關(guān)于MyBatis-Plus輸出完整SQL(帶參數(shù))的三種方案的文章就介紹到這了,更多相關(guān)MyBatis-Plus輸出完整SQL內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java Kafka實(shí)現(xiàn)延遲隊(duì)列的示例代碼
kafka作為一個使用廣泛的消息隊(duì)列,很多人都不會陌生。本文將利用Kafka實(shí)現(xiàn)延遲隊(duì)列,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以嘗試一下2022-08-08
Spring?Cloud?Alibaba微服務(wù)組件Sentinel實(shí)現(xiàn)熔斷限流
這篇文章主要為大家介紹了Spring?Cloud?Alibaba微服務(wù)組件Sentinel實(shí)現(xiàn)熔斷限流過程示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-06-06
MyBatis?與?Spring?Data?JPA?核心對比總結(jié)(選型指南與最佳實(shí)踐)
MyBatis和Spring?Data?JPA是Java兩大主流持久層框架,分別代表SQL可控性與面向?qū)ο箝_發(fā)效率的兩種設(shè)計(jì)哲學(xué),本文給大家介紹MyBatis與Spring?Data?JPA核心對比總結(jié),感興趣的朋友跟隨小編一起看看吧2025-11-11
Mybatis?Mapper中多參數(shù)方法不使用@param注解報錯的解決
這篇文章主要介紹了Mybatis?Mapper中多參數(shù)方法不使用@param注解報錯的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教。2022-01-01
Java JDK與cglib動態(tài)代理有什么區(qū)別
這篇文章主要介紹了Java JDK動態(tài)代理和cglib動態(tài)代理的區(qū)別文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧2023-03-03

