尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

MyBatisPlus SQL日志配置与性能优化实践

MyBatisPlus SQL日志配置与性能优化实践 1. MyBatisPlus打印SQL配置的必要性在Java持久层开发中SQL语句的调试和优化是每个开发者都会面临的挑战。MyBatisPlus作为MyBatis的增强工具虽然提供了强大的CRUD操作能力但在实际开发中我们经常需要查看框架最终生成的SQL语句以便进行性能调优或问题排查。打印SQL日志的需求主要来自以下几个场景验证动态条件拼接是否正确检查N1查询问题分析复杂联表查询的执行计划监控批量操作的SQL生成审计敏感数据操作2. 基础配置方式2.1 日志框架集成MyBatisPlus支持通过多种日志框架输出SQL语句以下是常见配置方式# application.yml 配置示例 mybatis-plus: configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 控制台输出或者使用SLF4JLogback组合!-- logback-spring.xml -- logger namecom.baomidou.mybatisplus levelDEBUG/2.2 多环境差异化配置在实际项目中我们通常需要区分开发环境和生产环境的日志级别Configuration public class MyBatisPlusConfig { Bean Profile({dev, test}) // 仅在开发测试环境生效 public PerformanceInterceptor performanceInterceptor() { PerformanceInterceptor interceptor new PerformanceInterceptor(); interceptor.setFormat(true); // 格式化SQL输出 interceptor.setMaxTime(1000); // 设置SQL执行超时阈值(ms) return interceptor; } }3. 高级配置技巧3.1 SQL美化输出默认的SQL日志可能难以阅读可以通过以下方式美化# 开启SQL格式化 mybatis-plus.configuration.log-implorg.apache.ibatis.logging.slf4j.Slf4jImpl logging.level.com.baomidou.mybatisplusTRACE配合Logback的PatternLayout自定义输出格式pattern%d{yyyy-MM-dd HH:mm:ss} | %-5level | %logger{36} - %msg%n/pattern3.2 敏感信息脱敏对于包含敏感数据的SQL建议配置脱敏规则public class SensitiveSqlLogger extends StdOutImpl { Override public void debug(String text) { text text.replaceAll((password|mobile)([^]*), $1****); super.debug(text); } }4. 性能监控与优化4.1 慢SQL监控配置慢SQL阈值并输出警告public class SlowSqlInterceptor implements Interceptor { private static final long SLOW_SQL_THRESHOLD 500; // ms Override public Object intercept(Invocation invocation) { long start System.currentTimeMillis(); Object result invocation.proceed(); long duration System.currentTimeMillis() - start; if(duration SLOW_SQL_THRESHOLD) { Statement stmt (Statement) invocation.getArgs()[0]; log.warn(Slow SQL detected: {} \n Execution time: {}ms, stmt.toString(), duration); } return result; } }4.2 执行计划分析结合EXPLAIN命令自动分析关键SQLAspect Component public class ExplainAspect { Pointcut(execution(* com.baomidou.mybatisplus.core.mapper.BaseMapper.*(..))) public void mapperMethods() {} Around(mapperMethods()) public Object addExplain(ProceedingJoinPoint pjp) throws Throwable { Object result pjp.proceed(); if (needExplain()) { Object param pjp.getArgs()[0]; if (param instanceof QueryWrapper) { QueryWrapper? wrapper (QueryWrapper?) param; String explainSql EXPLAIN wrapper.getSqlSelect(); // 执行explain并记录结果 } } return result; } }5. 生产环境最佳实践5.1 日志采样策略在高并发环境下全量SQL日志可能影响性能建议采用采样策略public class SamplingSqlLogger extends Slf4jImpl { private static final AtomicLong COUNTER new AtomicLong(); private static final int SAMPLE_RATE 100; // 1%采样率 Override public void debug(String s) { if (COUNTER.incrementAndGet() % SAMPLE_RATE 0) { super.debug(s); } } }5.2 上下文增强在分布式系统中为SQL日志添加追踪信息public class TraceSqlInterceptor implements Interceptor { Override public Object intercept(Invocation invocation) { MDC.put(traceId, TraceContext.getTraceId()); try { return invocation.proceed(); } finally { MDC.clear(); } } }6. 常见问题排查6.1 日志不输出问题排查检查日志级别是否正确设置确认没有多个日志框架冲突验证mybatis-plus配置是否正确加载检查是否有自定义的Logger实现覆盖了默认行为6.2 性能分析技巧当发现SQL执行缓慢时先确认是网络延迟还是SQL本身问题检查是否缺少索引分析执行计划中的全表扫描验证参数绑定是否正确7. 扩展应用场景7.1 审计日志记录将关键SQL操作记录到审计表public class AuditLogInterceptor implements Interceptor { Override public Object intercept(Invocation invocation) { Statement stmt (Statement) invocation.getArgs()[0]; if (isAuditOperation(stmt)) { auditService.logOperation( getCurrentUser(), stmt.toString(), System.currentTimeMillis() ); } return invocation.proceed(); } }7.2 动态数据源路由基于SQL特征实现读写分离public class DynamicDataSourceInterceptor { private static final SetString READ_OPERATIONS Set.of(SELECT, SHOW, EXPLAIN); public void beforeExecute(Statement stmt) { String sql stmt.toString().toUpperCase(); boolean isRead READ_OPERATIONS.stream().anyMatch(sql::startsWith); DynamicDataSourceHolder.setDataSourceType( isRead ? read : write ); } }在实际项目中合理的SQL日志配置可以大幅提升开发调试效率。建议根据项目阶段灵活调整日志级别开发环境可以使用DEBUG级别全面记录而生产环境则应采用WARN级别配合采样策略。同时要注意日志中的敏感信息保护避免数据泄露风险。
返回列表