Java手动打印执行过的sql

ops/2025/1/11 22:50:53/

1. 拦截器

java">package com.xxx.platform.common.interceptor;import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;
import com.xxx.platform.common.aop.OLAPQuery;
import com.xxx.platform.constant.CommonConstant;
import com.xxx.platform.util.SQLFormatHelper;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.cache.CacheKey;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.*;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;import java.lang.reflect.Method;
import java.util.Objects;
import java.util.Properties;/*** SQL查询统计拦截器。</p>** @author xxx* @version 1.0* @date 2022/10/27 18:21*/
@Component
@Intercepts({@Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class}),@Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class, CacheKey.class, BoundSql.class}),}
)
@Slf4j
public class SQLTimerInterceptor implements Interceptor {@Value("${spring.profiles.active}")private String profile;@Overridepublic Object intercept(Invocation invocation) throws Throwable {long startTime = System.currentTimeMillis();OLAPQuery olap = null;try {Method method = invocation.getMethod();olap = method.getAnnotation(OLAPQuery.class);if (!Objects.isNull(olap)) {DynamicDataSourceContextHolder.push(CommonConstant.PSS);}return invocation.proceed();} finally {if (!Objects.isNull(olap)) {DynamicDataSourceContextHolder.clear();}long duration = System.currentTimeMillis() - startTime;SQLFormatHelper.PrintSQL printSQL = SQLFormatHelper.getFormatSQL(invocation);String sqlId = printSQL.sqlId;String sql = printSQL.formatSQL;int ts = "lmp-sy-dev".equals(profile)?1000:3000;if (duration >= ts) {log.warn("{} execute SQL>=5s: {} ms, \nSQL: {}", sqlId, duration, sql);}}}@Overridepublic Object plugin(Object target) {return Plugin.wrap(target, this);}@Overridepublic void setProperties(Properties properties) {}}

2. 其他工具类

java">package com.xxx.platform.util;import org.apache.commons.collections.CollectionUtils;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.ParameterMapping;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.type.TypeHandlerRegistry;import java.text.DateFormat;
import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;/*** SQL格式化工具类。</p>* 将mybatis预编译SQL转换为带参数SQL。** @author xxx* @date 2023/02/01 15:54*/
public final class SQLFormatHelper {public static PrintSQL getFormatSQL(Invocation invocation) {PrintSQL sql = new PrintSQL();MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0];String sqlId = mappedStatement.getId();sql.sqlId = sqlId;try {Object parameter = null;if (invocation.getArgs().length > 1) {parameter = invocation.getArgs()[1];}BoundSql boundSql = mappedStatement.getBoundSql(parameter);Configuration configuration = mappedStatement.getConfiguration();String formatSQL = showSql(configuration, boundSql);sql.formatSQL = formatSQL;} catch (Exception e) {e.printStackTrace();BoundSql bs = (BoundSql)invocation.getArgs()[5];sql.formatSQL = bs.getSql();}return sql;}/*** 如果参数是String,则添加单引号, 如果是日期,则转换为时间格式器并加单引号;* 对参数是null和不是null的情况作了处理** @param obj obj* @return java.lang.String*/private static String getParameterValue(Object obj) {String value = null;if (obj instanceof String) {value = "'" + obj.toString() + "'";} else if (obj instanceof Date) {DateFormat formatter = DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.DEFAULT);value = "'" + formatter.format(new Date()) + "'";} else {if (obj != null) {value = obj.toString();} else {value = "";}}return value;}/*** 进行?的替换** @param configuration* @param boundSql* @return*/private static String showSql(Configuration configuration, BoundSql boundSql) {Object parameterObject = boundSql.getParameterObject();List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();String sql = boundSql.getSql().replaceAll("[\\s]+", " ");  // sql语句中多个空格都用一个空格代替if (!CollectionUtils.isEmpty(parameterMappings) && parameterObject != null) {// 获取类型处理器注册器,类型处理器的功能是进行java类型和数据库类型的转换<br>// 如果根据parameterObject.getClass()可以找到对应的类型,则替换TypeHandlerRegistry typeHandlerRegistry = configuration.getTypeHandlerRegistry();if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass())) {sql = sql.replaceFirst("\\?", Matcher.quoteReplacement(getParameterValue(parameterObject)));} else {// MetaObject主要是封装了originalObject对象,提供了get和set的方法用于获取和设置originalObject的属性值,主要支持对JavaBean、Collection、Map三种类型对象的操作MetaObject metaObject = configuration.newMetaObject(parameterObject);for (ParameterMapping parameterMapping : parameterMappings) {String propertyName = parameterMapping.getProperty();if (metaObject.hasGetter(propertyName)) {Object obj = metaObject.getValue(propertyName);sql = sql.replaceFirst("\\?", Matcher.quoteReplacement(getParameterValue(obj)));} else if (boundSql.hasAdditionalParameter(propertyName)) {Object obj = boundSql.getAdditionalParameter(propertyName);  // 该分支是动态sqlsql = sql.replaceFirst("\\?", Matcher.quoteReplacement(getParameterValue(obj)));} else {sql = sql.replaceFirst("\\?", "缺失");}}}}return sql;}public static class PrintSQL {public String sqlId;public String formatSQL;}
}

http://www.ppmy.cn/ops/149272.html

相关文章

在Ubuntu中使用systemd设置后台自启动服务

引言 在Ubuntu系统中&#xff0c;systemd 是一个非常强大的系统和服务管理器。它不仅负责系统的启动和初始化&#xff0c;还可以帮助我们管理各种后台服务。通过使用 systemd&#xff0c;我们可以轻松地设置服务在系统启动时自动运行&#xff0c;并且能够方便地管理服务的启动…

python实现自动登录12306抢票 -- selenium

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 python实现自动登录12306抢票 -- selenium 前言其实网上也出现了很多12306的代码&#xff0c;但是都不是最新的&#xff0c;我也是从网上找别人的帖子&#xff0c;看B站视频&…

HTTPS协议的基础与工作原理

什么是HTTPS&#xff1f; HTTPS&#xff08;HyperText Transfer Protocol Secure&#xff09;是HTTP协议的安全版本&#xff0c;它通过SSL/TLS协议对通信数据进行加密&#xff0c;确保数据的安全传输。与HTTP相比&#xff0c;HTTPS能防止数据被窃取、篡改或伪造&#xff0c;广…

基于微信小程序的水果销售系统的设计与实现springboot+论文源码调试讲解

第4章 系统设计 一个成功设计的系统在内容上必定是丰富的&#xff0c;在系统外观或系统功能上必定是对用户友好的。所以为了提升系统的价值&#xff0c;吸引更多的访问者访问系统&#xff0c;以及让来访用户可以花费更多时间停留在系统上&#xff0c;则表明该系统设计得比较专…

文件上传漏洞 (网络安全)

文件上传漏洞&#xff08;File Upload Vulnerability&#xff09;是一种常见的安全漏洞&#xff0c;发生在允许用户上传文件的应用程序中。如果系统没有适当验证用户上传文件的类型、内容或权限&#xff0c;就可能允许攻击者上传恶意文件&#xff0c;这些文件能够在目标服务器上…

如何在 Ubuntu 22.04 上安装和配置邮件服务器教程

简介&#xff1a; 在本指南中&#xff0c;我们将演示如何在 Ubuntu 22.04 上安装和配置邮件服务器&#xff0c;因为大中型公司可以从拥有私人邮件服务器中获益匪浅。通过使用邮件服务器&#xff0c;可以密切监视所有电子邮件流量。此外&#xff0c;自定义设置的灵活性使得建立…

Halcon在linux及ARM上的安装及c++工程化

一、HALCON下载 建议到HALCON官方下载页选择linux版本下载,压缩包名为MVTec_HALCON_Progress-18.11.0.1-linux(x64-aarch64-armv7a)-FullVersion.tar.gz。下载前需要登录HALCON帐号,如果没有请自行注册,填写一些基本信息然后激活邮件,操作方便简易。 下载许可证文件 该许…

linux相关conda操作

如果你想安装完整的 Anaconda&#xff08;而不是 Miniconda&#xff09;&#xff0c;Anaconda 是一个包含大量预安装科学计算包的发行版&#xff0c;适合数据科学和机器学习等领域。以下是详细的安装步骤和相关操作&#xff1a; 1. 安装 Anaconda 1.1 下载 Anaconda 安装脚本 …