package com.dy.common.mybatis; 
 | 
  
 | 
import org.apache.ibatis.mapping.BoundSql; 
 | 
import org.apache.ibatis.mapping.ParameterMapping; 
 | 
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.Locale; 
 | 
  
 | 
/** 
 | 
 * @Author: liurunyu 
 | 
 * @Date: 2024/12/13 10:39 
 | 
 * @Description 
 | 
 */ 
 | 
public class PrintSqlHelp { 
 | 
  
 | 
    /** 
 | 
     * 获取完整的执行SQL 
 | 
     */ 
 | 
    public static String getFullSql(Configuration configuration, BoundSql boundSql) { 
 | 
        try { 
 | 
            return parseAndExtractFullSql(configuration, boundSql); 
 | 
        } catch (Exception e) { 
 | 
            // 如果解析失败返回原始SQL 
 | 
            return boundSql.getSql(); 
 | 
        } 
 | 
    } 
 | 
  
 | 
    /** 
 | 
     * 组装完整的sql语句并把对应的参数都代入到sql语句里面 
 | 
     * 
 | 
     * @param configuration Configuration 
 | 
     * @param boundSql      BoundSql 
 | 
     * @return sql完整语句 
 | 
     */ 
 | 
    private static String parseAndExtractFullSql(Configuration configuration, BoundSql boundSql) { 
 | 
        // 获取mapper里面方法上的参数 
 | 
        Object sqlParameter = boundSql.getParameterObject(); 
 | 
        // sql语句里面需要的参数 
 | 
        List<ParameterMapping> parameterMappings = boundSql.getParameterMappings(); 
 | 
        // sql原始语句(?还没有替换成我们具体的参数) 
 | 
        String sql = boundSql.getSql().replaceAll("[\\s]+", " "); 
 | 
        if (!parameterMappings.isEmpty() && sqlParameter != null) { 
 | 
            // sql语句里面的?替换成真实的参数 
 | 
            TypeHandlerRegistry typeHandlerRegistry = configuration.getTypeHandlerRegistry(); 
 | 
            if (typeHandlerRegistry.hasTypeHandler(sqlParameter.getClass())) { 
 | 
                sql = sql.replaceFirst("\\?", getParameterValue(sqlParameter)); 
 | 
            } else { 
 | 
                MetaObject metaObject = configuration.newMetaObject(sqlParameter); 
 | 
                for (ParameterMapping parameterMapping : parameterMappings) { 
 | 
                    // 按顺序把?替换成对应的值 
 | 
                    String propertyName = parameterMapping.getProperty(); 
 | 
                    if (metaObject.hasGetter(propertyName)) { 
 | 
                        Object obj = metaObject.getValue(propertyName); 
 | 
                        sql = sql.replaceFirst("\\?", getParameterValue(obj)); 
 | 
                    } else if (boundSql.hasAdditionalParameter(propertyName)) { 
 | 
                        Object obj = boundSql.getAdditionalParameter(propertyName); 
 | 
                        sql = sql.replaceFirst("\\?", getParameterValue(obj)); 
 | 
                    } 
 | 
                } 
 | 
            } 
 | 
        } 
 | 
        return sql; 
 | 
    } 
 | 
  
 | 
  
 | 
    /** 
 | 
     * 获取参数对应的string值 
 | 
     * 
 | 
     * @param obj 参数对应的值 
 | 
     * @return string 
 | 
     */ 
 | 
    private static String getParameterValue(Object obj) { 
 | 
        String value; 
 | 
        if (obj instanceof String) { 
 | 
            value = "'" + obj + "'"; 
 | 
        } else if (obj instanceof Date) { 
 | 
            DateFormat formatter = 
 | 
                    DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.DEFAULT, Locale.CHINA); 
 | 
            value = "'" + formatter.format(obj) + "'"; 
 | 
        } else { 
 | 
            if (obj != null) { 
 | 
                value = obj.toString(); 
 | 
            } else { 
 | 
                value = ""; 
 | 
            } 
 | 
        } 
 | 
        // 对特殊字符进行转义,方便之后处理替换 
 | 
        return value != null ? makeQueryStringAllRegExp(value) : ""; 
 | 
    } 
 | 
  
 | 
  
 | 
  
 | 
    /** 
 | 
     * 转义正则特殊字符 ($()*+.[]?\^{} 
 | 
     * \\需要第一个替换,否则replace方法替换时会有逻辑bug 
 | 
     */ 
 | 
    private static String makeQueryStringAllRegExp(String str) { 
 | 
        if (str != null && !"".equals(str)) { 
 | 
            return str.replace("\\", "\\\\") 
 | 
                    .replace("*", "\\*") 
 | 
                    .replace("+", "\\+") 
 | 
                    .replace("|", "\\|") 
 | 
                    .replace("{", "\\{") 
 | 
                    .replace("}", "\\}") 
 | 
                    .replace("(", "\\(") 
 | 
                    .replace(")", "\\)") 
 | 
                    .replace("^", "\\^") 
 | 
                    .replace("$", "\\$") 
 | 
                    .replace("[", "\\[") 
 | 
                    .replace("]", "\\]") 
 | 
                    .replace("?", "\\?") 
 | 
                    .replace(",", "\\,") 
 | 
                    .replace(".", "\\.") 
 | 
                    .replace("&", "\\&"); 
 | 
        } 
 | 
        return str; 
 | 
    } 
 | 
} 
 |