个利用正则表达式解析单句SQL的类SqlParser
2008-08-25 16:31 Kevin-wang 阅读(642) 评论(0) 编辑 收藏 举报
一个利用正则表达式解析单句SQL的类SqlParser
|
先看要解析的样例SQL语句:
select * from dual SELECT * frOm dual Select C1,c2 From tb select c1,c2 from tb select count(*) from t1 select c1,c2,c3 from t1 where condi1=1 Select c1,c2,c3 From t1 Where condi1=1 select c1,c2,c3 from t1,t2 where condi3=3 or condi4=5 order by o1,o2 Select c1,c2,c3 from t1,t2 Where condi3=3 or condi4=5 Order by o1,o2 select c1,c2,c3 from t1,t2,t3 where condi1=5 and condi6=6 or condi7=7 group by g1,g2 Select c1,c2,c3 From t1,t2,t3 Where condi1=5 and condi6=6 or condi7=7 Group by g1,g2 Select c1,c2,c3 From t1,t2,t3 Where condi1=5 and condi6=6 or condi7=7 Group by g1,g2,g3 order by g2,g3 解析效果之一(isSingleLine=false): 原SQL为select * from dual 解析后的SQL为 select * from dual 原SQL为SELECT * frOm dual 解析后的SQL为 select * from dual 原SQL为Select C1,c2 From tb 解析后的SQL为 select C1,c2 from tb 原SQL为select c1,c2 from tb 解析后的SQL为 select c1,c2 from tb 原SQL为select count(*) from t1 解析后的SQL为 select count(*) from t1 原SQL为select c1,c2,c3 from t1 where condi1=1 解析后的SQL为 select c1,c2,c3 from t1 where condi1=1 原SQL为Select c1,c2,c3 From t1 Where condi1=1 解析后的SQL为 select c1,c2,c3 from t1 where condi1=1 原SQL为select c1,c2,c3 from t1,t2 where condi3=3 or condi4=5 order by o1,o2 解析后的SQL为 select c1,c2,c3 from t1,t2 where condi3=3 or condi4=5 order by o1,o2 原SQL为Select c1,c2,c3 from t1,t2 Where condi3=3 or condi4=5 Order by o1,o2 解析后的SQL为 select c1,c2,c3 from t1,t2 where condi3=3 or condi4=5 order by o1,o2 原SQL为select c1,c2,c3 from t1,t2,t3 where condi1=5 and condi6=6 or condi7=7 group by g1,g2 解析后的SQL为 select c1,c2,c3 from t1,t2,t3 where condi1=5 and condi6=6 or condi7=7 group by g1,g2 原SQL为Select c1,c2,c3 From t1,t2,t3 Where condi1=5 and condi6=6 or condi7=7 Group by g1,g2 解析后的SQL为 select c1,c2,c3 from t1,t2,t3 where condi1=5 and condi6=6 or condi7=7 group by g1,g2 原SQL为Select c1,c2,c3 From t1,t2,t3 Where condi1=5 and condi6=6 or condi7=7 Group by g1,g2,g3 order by g2,g3 解析后的SQL为 select c1,c2,c3 from t1,t2,t3 where condi1=5 and condi6=6 or condi7=7 group by g1,g2,g3 order by g2,g3 解析效果之二(isSingleLine=true): 原SQL为select * from dual 解析后的SQL为 select * from dual 原SQL为SELECT * frOm dual 解析后的SQL为 select * from dual 原SQL为Select C1,c2 From tb 解析后的SQL为 select C1, c2 from tb 原SQL为select c1,c2 from tb 解析后的SQL为 select c1, c2 from tb 原SQL为select count(*) from t1 解析后的SQL为 select count(*) from t1 原SQL为select c1,c2,c3 from t1 where condi1=1 解析后的SQL为 select c1, c2, c3 from t1 where condi1=1 原SQL为Select c1,c2,c3 From t1 Where condi1=1 解析后的SQL为 select c1, c2, c3 from t1 where condi1=1 原SQL为select c1,c2,c3 from t1,t2 where condi3=3 or condi4=5 order by o1,o2 解析后的SQL为 select c1, c2, c3 from t1, t2 where condi3=3 or condi4=5 order by o1, o2 原SQL为Select c1,c2,c3 from t1,t2 Where condi3=3 or condi4=5 Order by o1,o2 解析后的SQL为 select c1, c2, c3 from t1, t2 where condi3=3 or condi4=5 order by o1, o2 原SQL为select c1,c2,c3 from t1,t2,t3 where condi1=5 and condi6=6 or condi7=7 group by g1,g2 解析后的SQL为 select c1, c2, c3 from t1, t2, t3 where condi1=5 and condi6=6 or condi7=7 group by g1, g2 原SQL为Select c1,c2,c3 From t1,t2,t3 Where condi1=5 and condi6=6 or condi7=7 Group by g1,g2 解析后的SQL为 select c1, c2, c3 from t1, t2, t3 where condi1=5 and condi6=6 or condi7=7 group by g1, g2 原SQL为Select c1,c2,c3 From t1,t2,t3 Where condi1=5 and condi6=6 or condi7=7 Group by g1,g2,g3 order by g2,g3 解析后的SQL为 select c1, c2, c3 from t1, t2, t3 where condi1=5 and condi6=6 or condi7=7 group by g1, g2, g3 order by g2, g3 使用的类SqlParser,你可以拷贝下来使用之: package com.sitinspring.common.sqlFormatter; import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * SQL语句解析器类 * @author: sitinspring(junglesong@gmail.com) * @date: 2008-3-12 */ public class SqlParser{ /** * 逗号 */ private static final String Comma = ","; /** * 四个空格 */ private static final String FourSpace = " "; /** * 是否单行显示字段,表,条件的标识量 */ private static boolean isSingleLine=true; /** * 待解析的SQL语句 */ private String sql; /** * SQL中选择的列 */ private String cols; /** * SQL中查找的表 */ private String tables; /** * 查找条件 */ private String conditions; /** * Group By的字段 */ private String groupCols; /** * Order by的字段 */ private String orderCols; /** * 构造函数 * 功能:传入构造函数,解析成字段,表,条件等 * @param sql:传入的SQL语句 */ public SqlParser(String sql){ this.sql=sql.trim(); parseCols(); parseTables(); parseConditions(); parseGroupCols(); parseOrderCols(); } /** * 解析选择的列 * */ private void parseCols(){ String regex="(select)(.+)(from)"; cols=getMatchedString(regex,sql); } /** * 解析选择的表 * */ private void parseTables(){ String regex=""; if(isContains(sql,"\\s+where\\s+")){ regex="(from)(.+)(where)"; } else{ regex="(from)(.+)($)"; } tables=getMatchedString(regex,sql); } /** * 解析查找条件 * */ private void parseConditions(){ String regex=""; if(isContains(sql,"\\s+where\\s+")){ // 包括Where,有条件 if(isContains(sql,"group\\s+by")){ // 条件在where和group by之间 regex="(where)(.+)(group\\s+by)"; } else if(isContains(sql,"order\\s+by")){ // 条件在where和order by之间 regex="(where)(.+)(order\\s+by)"; } else{ // 条件在where到字符串末尾 regex="(where)(.+)($)"; } } else{ // 不包括where则条件无从谈起,返回即可 return; } conditions=getMatchedString(regex,sql); } /** * 解析GroupBy的字段 * */ private void parseGroupCols(){ String regex=""; if(isContains(sql,"group\\s+by")){ // 包括GroupBy,有分组字段 if(isContains(sql,"order\\s+by")){ // group by 后有order by regex="(group\\s+by)(.+)(order\\s+by)"; } else{ // group by 后无order by regex="(group\\s+by)(.+)($)"; } } else{ // 不包括GroupBy则分组字段无从谈起,返回即可 return; } groupCols=getMatchedString(regex,sql); } /** * 解析OrderBy的字段 * */ private void parseOrderCols(){ String regex=""; if(isContains(sql,"order\\s+by")){ // 包括GroupBy,有分组字段 regex="(order\\s+by)(.+)($)"; } else{ // 不包括GroupBy则分组字段无从谈起,返回即可 return; } orderCols=getMatchedString(regex,sql); } /** * 从文本text中找到regex首次匹配的字符串,不区分大小写 * @param regex: 正则表达式 * @param text:欲查找的字符串 * @return regex首次匹配的字符串,如未匹配返回空 */ private static String getMatchedString(String regex,String text){ Pattern pattern=Pattern.compile(regex,Pattern.CASE_INSENSITIVE); Matcher matcher=pattern.matcher(text); while(matcher.find()){ return matcher.group(2); } return null; } /** * 看word是否在lineText中存在,支持正则表达式 * @param lineText * @param word * @return */ private static boolean isContains(String lineText,String word){ Pattern pattern=Pattern.compile(word,Pattern.CASE_INSENSITIVE); Matcher matcher=pattern.matcher(lineText); return matcher.find(); } public String toString(){ // 无法解析则原样返回 if(cols==null && tables==null && conditions==null && groupCols==null && orderCols==null ){ return sql; } StringBuffer sb=new StringBuffer(); sb.append("原SQL为"+sql+"\n"); sb.append("解析后的SQL为\n"); for(String str:getParsedSqlList()){ sb.append(str); } sb.append("\n"); return sb.toString(); } /** * 在分隔符后加上回车 * @param str * @param splitStr * @return */ private static String getAddEnterStr(String str,String splitStr){ Pattern p = Pattern.compile(splitStr,Pattern.CASE_INSENSITIVE); // 用Pattern类的matcher()方法生成一个Matcher对象 Matcher m = p.matcher(str); StringBuffer sb = new StringBuffer(); // 使用find()方法查找第一个匹配的对象 boolean result = m.find(); // 使用循环找出模式匹配的内容替换之,再将内容加到sb里 while (result) { m.appendReplacement(sb, m.group(0) + "\n "); result = m.find(); } // 最后调用appendTail()方法将最后一次匹配后的剩余字符串加到sb里; m.appendTail(sb); return FourSpace+sb.toString(); } /** * 取得解析的SQL字符串列表 * @return */ public List<String> getParsedSqlList(){ List<String> sqlList=new ArrayList<String>(); // 无法解析则原样返回 if(cols==null && tables==null && conditions==null && groupCols==null && orderCols==null ){ sqlList.add(sql); return sqlList; } if(cols!=null){ sqlList.add("select\n"); if(isSingleLine){ sqlList.add(getAddEnterStr(cols,Comma)); } else{ sqlList.add(FourSpace+cols); } } if(tables!=null){ sqlList.add(" \nfrom\n"); if(isSingleLine){ sqlList.add(getAddEnterStr(tables,Comma)); } else{ sqlList.add(FourSpace+tables); } } if(conditions!=null){ sqlList.add(" \nwhere\n"); if(isSingleLine){ sqlList.add(getAddEnterStr(conditions,"(and|or)")); } else{ sqlList.add(FourSpace+conditions); } } if(groupCols!=null){ sqlList.add(" \ngroup by\n"); if(isSingleLine){ sqlList.add(getAddEnterStr(groupCols,Comma)); } else{ sqlList.add(FourSpace+groupCols); } } if(orderCols!=null){ sqlList.add(" \norder by\n"); if(isSingleLine){ sqlList.add(getAddEnterStr(orderCols,Comma)); } else{ sqlList.add(FourSpace+orderCols); } } return sqlList; } /** * 设置是否单行显示表,字段,条件等 * @param isSingleLine */ public static void setSingleLine(boolean isSingleLine) { SqlParser.isSingleLine = isSingleLine; } /** * 测试 * @param args */ public static void main(String[] args){ List<String> ls=new ArrayList<String>(); ls.add("select * from dual"); ls.add("SELECT * frOm dual"); ls.add("Select C1,c2 From tb"); ls.add("select c1,c2 from tb"); ls.add("select count(*) from t1"); ls.add("select c1,c2,c3 from t1 where condi1=1 "); ls.add("Select c1,c2,c3 From t1 Where condi1=1 "); ls.add("select c1,c2,c3 from t1,t2 where condi3=3 or condi4=5 order by o1,o2"); ls.add("Select c1,c2,c3 from t1,t2 Where condi3=3 or condi4=5 Order by o1,o2"); ls.add("select c1,c2,c3 from t1,t2,t3 where condi1=5 and condi6=6 or condi7=7 group by g1,g2"); ls.add("Select c1,c2,c3 From t1,t2,t3 Where condi1=5 and condi6=6 or condi7=7 Group by g1,g2"); ls.add("Select c1,c2,c3 From t1,t2,t3 Where condi1=5 and condi6=6 or condi7=7 Group by g1,g2,g3 order by g2,g3"); for(String sql:ls){ System.out.println(new SqlParser(sql)); //System.out.println(sql); } } } |