注:文章皆为个人纪录,可用性请以最终结果为准,若有错还请大佬们指出,谢谢!
FunctionTest
package com.jxz.function;
import com.jxz.StrUtils;
import org.junit.platform.commons.util.StringUtils;
import org.springframework.stereotype.Component;
import java.util.LinkedList;
import java.util.List;
/**
* @Description: 将预编译sql与参数拼接为完整 sql, 完整sql可直接在数据库查询中运行
*
* 操作方法: 修改 SQL 与 PARAMS 的值即可, main 方法无需任何改动, 直接运行
*
* @Date: 2022/09/02
* @Author: jiangXueZhi
*/
@Component
public class FunctionTest {
/** 日志中的预编译sql (带有占位符的sql), 保持如下换行格式, 方便超长字符串的删除/覆盖*/
private static final String SQL =
"Preparing: SELECT id,name,age,create_time,update_time FROM disbursement_fee WHERE (name IN (?,?,?))";
/** 日志中预编译sql对应的参数, 保持如下换行格式, 方便超长字符串的删除/覆盖*/
private static final String PARAMS =
"Parameters: 张三(String), 李四(String), 王五(String)";
/**
* 拼接 MybatisPlus 的预编译 sql 及 参数
*/
public static void main(String[] args) {
if (StringUtils.isNotBlank(SQL) && StringUtils.isNotBlank(PARAMS)) {
String sqlTemp = SQL.replace("Preparing: ", "").trim();
String paramsTemp = PARAMS.replace("Parameters: ", "").trim();
List<Object> paramValidStrList = new LinkedList<>(); // 有效的参数集合
String[] paramList = paramsTemp.split(", ");
for (String s : paramList) {
if (s.endsWith("(Integer)")) {
paramValidStrList.add(s.replace("(Integer)", "").trim());
} else {
int times = s.length() - s.replace("(", "").length(); // ( 字符的个数
int index = StrUtils.getIndexBySpecialChar(s, "\\(", times);
paramValidStrList.add("'" + s.substring(0, index) + "'"); // 确认倒数第二个"("的下标索引
}
}
int times = sqlTemp.length() - sqlTemp.replace("?", "").length(); // ? 占位符的个数
if (paramValidStrList.size() == times) {
StringBuilder finalSql = new StringBuilder(sqlTemp);
for (int i = 1; i <= paramValidStrList.size(); i++) {
int index = StrUtils.getIndexBySpecialChar(String.valueOf(finalSql), "\\?", 1);
finalSql.replace(index, index + 1, paramValidStrList.get(i - 1).toString());
}
System.out.println("\n完整拼接的SQL如下:\n\n" + finalSql + "\n");
}
}
}
}
StrUtils
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* 查询某个指定字符在字符串中第几次出现的下标位置
*
* @param str 字符串
* @param character 指定字符 (需要加转义字符 否则报错:PatternSyntaxException)
* @param times 第几次出现
* @return 下标位置
*/
public static int getIndexBySpecialChar(String str, String character, int times) {
Pattern pattern = Pattern.compile(character);
Matcher findMatcher = pattern.matcher(str);
//标记遍历字符串的位置
int indexNum=0;
while(findMatcher.find()) {
indexNum++;
if(indexNum==times){
break;
}
}
return findMatcher.start();
}