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;
|
}
|
}
|