Java将SQL解析为SQL模板
/** * 获取sql模板 */ public String extraSqlTemplate(String sqlContent) { if (StringUtils.isBlank(sqlContent)) { return ""; } String[] sqlContentArr = sqlContent.split(""); String sqlTemplate = ""; // 是否开始引号 Boolean isQuoteStart = Boolean.FALSE; // 是否开始数字 Boolean isNumberStart = Boolean.FALSE; String lastSqlContentItem = ""; Integer count = 1; for (String item : sqlContentArr) { // 从字符串中抽取引号部分为模板 if (item.equals("\'")) { isQuoteStart = !isQuoteStart; if (!isQuoteStart) { count++; continue; } sqlTemplate = sqlTemplate + "?"; lastSqlContentItem = item; count++; continue; } if (isQuoteStart) { count++; continue; } // 从字符串中抽取数字部分为模板 // 当最后一个字符为数字,并且有where条件时,需要替代数字 if (count == sqlContentArr.length && item.matches("\\d+") && sqlContent.toLowerCase().contains("where")) { sqlTemplate = sqlTemplate + "?"; lastSqlContentItem = item; isNumberStart = Boolean.FALSE; count++; continue; } // 当前字符为数字,上一个字符不是字母、下划线、数字时,数字校验开关打开 if (item.matches("\\d+") && !CommonUtil.isLetter(lastSqlContentItem) && !lastSqlContentItem.equalsIgnoreCase("_") && !lastSqlContentItem.matches("\\d+")) { isNumberStart = Boolean.TRUE; lastSqlContentItem = item; count++; continue; } // 数字校验开关打开,并且当前字符为数字,无需处理 if (isNumberStart && item.matches("\\d+")) { lastSqlContentItem = item; count++; continue; } // 当前字符不是数字,上一个字符为数字,数字校验开关为打开状态,则需要替代数字 if (!item.matches("\\d+") && lastSqlContentItem.matches("\\d+") && isNumberStart) { sqlTemplate = sqlTemplate + "?"+item; lastSqlContentItem = item; isNumberStart = Boolean.FALSE; count++; continue; } sqlTemplate = sqlTemplate + item; lastSqlContentItem = item; count++; } return sqlTemplate; }