最近因为工作需要写了一个工具类 可以从insert语句中提取充每个字段 以及填写的参数。
如果参数中存在sql函数 也可以准确提取出来 分享给大家
定义这样一个sql
String insert="insert into test(col1, col2 , col3, \n col4,col5,col6,col7,col8) " +
"values('',123,'测试(彩色',123,'',dateformat(sdfsdf,'erter',test(test(111,test('222')))),'测试2\n彩色',now('test',1123))";
语句中存在 空格 回车 字符串 嵌套了一些函数 然后从里面提取出 八个列 和八个参数来
首先写一个工具类如下
package com.aheadframework.core.util.sql;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class SqlUtil {
public static String trim(String str){
String values=values(str);
values=values.substring(values.indexOf("("));
StringBuffer sb=new StringBuffer(values);
boolean delete=true;
boolean flag=true;
int start=0;
while (flag){
char c=sb.charAt(start);
if(compare(c,'\'')){
delete=!delete;
}
if((compare(c,'\n')&&delete)
||(compare(c,' ')&&delete)){
sb.deleteCharAt(start);
}else{
start++;
}
if(start>=sb.length()){
break;
}
}
return sb.toString();
}
private static String values(String str) {
String ls=str.toLowerCase();
int valueIndex=ls.indexOf("values");
//int valueIndex= index1==-1?index2:index1;
String values=str.substring(valueIndex);
return values;
}
public static String[] columns(String str) {
int start1=str.indexOf("(");
int end=str.indexOf(")");
String values=str.substring(start1+1,end);
values=values.replaceAll("\n","")
.replaceAll(" ","");
return values.split(",");
}
public static List params(String sql){
String values=trim(sql);
boolean flag=true;
int startIndex=0;
int endIndex=0;
boolean param=false;
boolean fh=false;
int start=1;
int t=0;
boolean str=false;
List params=new ArrayList<>();
while(flag){
char pri=values.charAt(start-1);
char c=values.charAt(start);
//char next=values.charAt(start+1);
//System.out.println(pri+" "+c+" "+param);
if(!param&&(compare(pri,'(')||compare(pri,','))){
if(compare(c,'\'')){
startIndex=start+1;
str=true;
fh=true;
}else{
startIndex=start;
str=false;
fh=false;
}
param=true;
}
//System.out.println(c+" "+startIndex+" "+param);
if(param){
if(t==0&&(compare(c,',')||compare(c,')'))){
//System.out.println("values "+values.substring(startIndex));
if(compare(pri,'\'')&&fh){
endIndex=start-1;
String v=values.substring(startIndex,endIndex);
params.add(v);
param=false;
//System.out.println("v "+v);
}else if(notCompare(pri,'\'')&&!fh){
endIndex=start;
String v=values.substring(startIndex,endIndex);
params.add(v);
param=false;
//System.out.println("v "+v);
}
}
if(compare(c,'(')&&!str){
t++;
}
//System.out.println("t++ "+t);
if(compare(c,')')&&!str&&t>0){
t--;
}
//System.out.println("t-- "+t);
}
start++;
if(start>=values.length()){
break;
}
}
return params;
}
public static boolean compare(char c,char c1){
return c==c1;
}
public static boolean notCompare(char c,char c1){
return c!=c1;
}
public static void main(String[] args) {
//写一个测试sql
String insert="insert into test(col1, col2 , col3, \n col4,col5,col6,col7,col8) " +
"values('',123,'测试(彩色',123,'',dateformat(sdfsdf,'erter',\n test(test(111,test('222')))),'测试2\n彩色',now('test',1123))";
//返回列
String[] str=SqlUtil.columns(insert);
//返回参数
List list=SqlUtil.params(insert);
System.out.println(insert);
System.out.println(Arrays.toString(str)+" 列数量 "+str.length+" 参数数量 "+list.size());
for(String s:list){
System.out.println("参数 "+s);
}
}
}
然后写个测试方法
public static void main(String[] args) {
//写一个测试sql
String insert="insert into test(col1, col2 , col3, \n col4,col5,col6,col7,col8) " +
"values('',123,'测试(彩色',123,'',dateformat(sdfsdf,'erter',\n test(test(111,test('222')))),'测试2\n彩色',now('test',1123))";
//返回列
String[] str=SqlUtil.columns(insert);
//返回参数
List list=SqlUtil.params(insert);
System.out.println(insert);
System.out.println(Arrays.toString(str)+" 列数量 "+str.length+" 参数数量 "+list.size());
for(String s:list){
System.out.println("参数 "+s);
}
}
提取出了
[col1, col2, col3, col4, col5, col6, col7, col8] 八个列
以及八个参数(包括参数里的 括号 和回车)
参数 1、
参数 2、 123
参数 3、 测试(彩色
参数 4、 123
参数 5、
参数 6、 dateformat(sdfsdf,‘erter’,test(test(111,test(‘222’))))
参数 7、 测试2
彩色
参数 8、 now(‘test’,1123)
以上的代码都封装在了我写的工具包里
源码位置: https://github.com/niupengyu/ahead-framework.git.
有兴趣的可以下载 ,如果已下载 可以尝试更新。 互相交流。
另外还有其他工具类以后分享给大家。