一个利用正则表达式解析单句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);
        }
    }
}

转载于:https://www.cnblogs.com/pelephone/articles/sql-parse-java.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值