123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136 |
- package com.welampiot.configuration;
- import org.apache.commons.collections4.CollectionUtils;
- 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.stereotype.Component;
- import java.sql.Statement;
- import java.text.DateFormat;
- import java.util.Date;
- import java.util.List;
- import java.util.Locale;
- import java.util.Properties;
- import java.util.regex.Matcher;
- @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})
- })
- @Component
- public class LastSqlInterceptor implements Interceptor {
- public String sqlContent;
- //获取sql语句
- @Override
- public Object intercept(Invocation invocation) throws Throwable {
- // 耗时开始时间
- long startTime = System.currentTimeMillis();
- // 获取 StatementHandler ,默认是 RoutingStatementHandler
- StatementHandler statementHandler = (StatementHandler) invocation.getTarget();
- // 获取 StatementHandler 包装类
- MetaObject metaObjectHandler = SystemMetaObject.forObject(statementHandler);
- // 获取查询接口映射的相关信息
- MappedStatement mappedStatement = (MappedStatement) metaObjectHandler.getValue("delegate.mappedStatement");
- // 获取请求时的参数
- Object parameterObject = statementHandler.getParameterHandler().getParameterObject();
- // 获取sql
- String sql = showSql(mappedStatement.getConfiguration(), mappedStatement.getBoundSql(parameterObject));
- // 获取执行sql方法
- String sqlId = mappedStatement.getId();
- // 执行sql
- Object result = invocation.proceed();
- // 计算总耗时
- long cost = System.currentTimeMillis() - startTime;
- System.out.println(" ======> SQL方法 : {} , 总耗时 : {}毫秒, SQL语句 : {} "+ sqlId+"----"+cost+"----"+sql);
- this.sqlContent = sql;
- return result;
- }
- /**
- * 拦截器对应的封装原始对象的方法,获取代理对象
- */
- @Override
- public Object plugin(Object target) {
- return (target instanceof StatementHandler) ? Plugin.wrap(target, this) : target;
- }
- /**
- * 设置注册拦截器时设定的属性,设置代理对象的参数
- */
- @Override
- public void setProperties(Properties properties) {
- }
- private static String showSql(Configuration configuration, BoundSql boundSql) {
- // 获取参数
- Object parameterObject = boundSql.getParameterObject();
- List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
- // sql语句中多个空格都用一个空格代替
- String sql = boundSql.getSql().replaceAll("[\\s]+", " ");
- if (CollectionUtils.isNotEmpty(parameterMappings) && parameterObject != null) {
- // 获取类型处理器注册器,类型处理器的功能是进行java类型和数据库类型的转换
- TypeHandlerRegistry typeHandlerRegistry = configuration.getTypeHandlerRegistry();
- // 如果根据parameterObject.getClass()可以找到对应的类型,则替换
- 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)) {
- // 该分支是动态sql
- Object obj = boundSql.getAdditionalParameter(propertyName);
- sql = sql.replaceFirst("\\?", Matcher.quoteReplacement(getParameterValue(obj)));
- } else {
- // 打印出缺失,提醒该参数缺失并防止错位
- sql = sql.replaceFirst("\\?", "缺失");
- }
- }
- }
- }
- return sql;
- }
- private static String getParameterValue(Object obj) {
- String value;
- if (obj instanceof String) {
- value = "'" + obj.toString() + "'";
- }
- else if (obj instanceof Date) {
- DateFormat formatter = DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.DEFAULT, Locale.CHINA);
- value = "'" + formatter.format(new Date()) + "'";
- }
- else {
- if (obj != null) {
- value = obj.toString();
- } else {
- value = "";
- }
- }
- return value;
- }
- }
|