SpringBoot整合Mybatis格式化运行SQL以及SQL运行时间

本文介绍了如何在SpringBoot项目中整合Mybatis,以实现SQL语句的格式化显示和运行时间的监控。通过示例代码,展示了关键配置和操作步骤,帮助开发者更好地理解和优化数据库查询性能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  1. 主要代码如下所示:
package com.aoke.oa.search.plugins;

import com.baomidou.mybatisplus.core.toolkit.PluginUtils;
import com.baomidou.mybatisplus.core.toolkit.SystemClock;
import com.baomidou.mybatisplus.core.toolkit.sql.SqlFormatter;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.ParameterMapping;
import org.apache.ibatis.plugin.*;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.SystemMetaObject;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.type.TypeHandlerRegistry;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component;

import java.sql.Statement;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Properties;

/**
 * 用于输出每条 SQL 语句及其执行时间 
 */
@Slf4j
@Intercepts({
   
        @Signature(type = StatementHandler.class, method = "query", args = {
   Statement.class, ResultHandler.class}),
        @Signature(type = StatementHandler.class, method = "update", args = Statement.class),
        @Signature(type = StatementHandler.class, method = "batch", args = Statement.class)
})
// 当由此属于才能回注入该bean进入Spring
@ConditionalOnProperty(value = "oa.search.log.sql.enabled", havingValue = "true", matchIfMissing = true)
@Component
public class SqlLogInterceptor implements Interceptor {
   


    @Override
    public Object intercept(Invocation invocation) throws Throwable {
   

        // 计算执行 SQL 耗时
        long timing = 0L;
        Object result = null;
        try {
   
            long start = SystemClock.now();
            result = invocation.proceed();
            timing = SystemClock.now() - start;
        } finally {
   

            // SQL 打印执行结果
            // 获取真正的代理对象
            Object target = PluginUtils.realTarget(invocation.getTarget());
            MetaObject metaObject = SystemMetaObject.forObject(target);
				
			// 获取执行的MappedStatement
            MappedStatement ms = (MappedStatement) metaObject.getValue("delegate.mappedStatement");

            // 获取运行的SQL
            BoundSql boundSql = (BoundSql) metaObject.getValue("delegate.boundSql");
            Configuration configuration = ms.getConfiguration();

            //查询参数
            List<Object> params = getRuntimeParams(configuration, boundSql);

            String runTimeSql = getRuntimeSql(boundSql, params);
            SqlFormatter sqlFormatter = new SqlFormatter();
            String formatterSql = sqlFormatter.format(runTimeSql);

            // 打印 sql
            log.info("\n==============  Sql Start  ==============" +
                            "\nExecute Time:{} ms - ID:{}" +
                            "\nExecute SQL :{}" +
                            "\n==============  Sql  End   ==============",
                    timing, ms.getId(), formatterSql);
        }
        return result;
    }

    /**
     * 取得运行时的SQL 替换对应的参数
     */
    private String getRuntimeSql(BoundSql boundSql, List<Object> params) {
   
        String sql = boundSql.getSql();
        for (Object object : params) {
   
            sql = sql.replaceFirst("\\?", getParameterValue(object));
        }
        return sql;
    }

    /**
     * 取得运行时的参数
     */
    private static List<Object> getRuntimeParams(Configuration configuration, BoundSql boundSql) {
   
        List<Object> params = 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值