将预编译sql与参数拼接为完整 sql, 完整sql可直接在数据库查询中运行

注:文章皆为个人纪录,可用性请以最终结果为准,若有错还请大佬们指出,谢谢!

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

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值