单句SQL语句的解析方案
2009-02-05 10:20:54 来源:WEB开发网下面是BaseSingleSqlParser的五种子类:
package com.sitinspring.common.sqlparser.single;
import com.sitinspring.common.sqlparser.SqlSegment;
/** *//**
*
* 单句删除语句解析器
* @author 何杨(heyang78@gmail.com)
*
* @since 2009年2月3日8:58:48
* @version 1.00
*/
public class DeleteSqlParser extends BaseSingleSqlParser{
public DeleteSqlParser(String originalSql) {
super(originalSql);
}
@Override
protected void initializeSegments() {
segments.add(new SqlSegment("(delete from)(.+)( where | ENDOFSQL)","[,]"));
segments.add(new SqlSegment("(where)(.+)( ENDOFSQL)","(and|or)"));
}
}
package com.sitinspring.common.sqlparser.single;
import com.sitinspring.common.sqlparser.SqlSegment;
/** *//**
*
* 单句查询插入语句解析器
* @author 何杨(heyang78@gmail.com)
*
* @since 2009年2月3日9:41:23
* @version 1.00
*/
public class InsertSelectSqlParser extends BaseSingleSqlParser{
public InsertSelectSqlParser(String originalSql) {
super(originalSql);
}
@Override
protected void initializeSegments() {
segments.add(new SqlSegment("(insert into)(.+)( select )","[,]"));
segments.add(new SqlSegment("(select)(.+)(from)","[,]"));
segments.add(new SqlSegment("(from)(.+)( where | on | having | groups+by | orders+by | ENDOFSQL)","(,|s+lefts+joins+|s+rights+joins+|s+inners+joins+)"));
segments.add(new SqlSegment("(where|on|having)(.+)( groups+by | orders+by | ENDOFSQL)","(and|or)"));
segments.add(new SqlSegment("(groups+by)(.+)( orders+by| ENDOFSQL)","[,]"));
segments.add(new SqlSegment("(orders+by)(.+)( ENDOFSQL)","[,]"));
}
}
package com.sitinspring.common.sqlparser.single;
import com.sitinspring.common.sqlparser.SqlSegment;
/** *//**
*
* 单句插入语句解析器
* @author 何杨(heyang78@gmail.com)
*
* @since 2009年2月3日9:16:44
* @version 1.00
*/
public class InsertSqlParser extends BaseSingleSqlParser{
public InsertSqlParser(String originalSql) {
super(originalSql);
}
@Override
protected void initializeSegments() {
segments.add(new SqlSegment("(insert into)(.+)([(])","[,]"));
segments.add(new SqlSegment("([(])(.+)( [)] values )","[,]"));
segments.add(new SqlSegment("([)] values [(])(.+)( [)])","[,]"));
}
@Override
public String getParsedSql() {
String retval=super.getParsedSql();
retval=retval+")";
return retval;
}
}
package com.sitinspring.common.sqlparser.single;
import com.sitinspring.common.sqlparser.SqlSegment;
/** *//**
*
* 单句查询语句解析器
* @author 何杨(heyang78@gmail.com)
*
* @since 2009-2-2 下午03:30:54
* @version 1.00
*/
public class SelectSqlParser extends BaseSingleSqlParser{
public SelectSqlParser(String originalSql) {
super(originalSql);
}
@Override
protected void initializeSegments() {
segments.add(new SqlSegment("(select)(.+)(from)","[,]"));
segments.add(new SqlSegment("(from)(.+)( where | on | having | groups+by | orders+by | ENDOFSQL)","(,|s+lefts+joins+|s+rights+joins+|s+inners+joins+)"));
segments.add(new SqlSegment("(where|on|having)(.+)( groups+by | orders+by | ENDOFSQL)","(and|or)"));
segments.add(new SqlSegment("(groups+by)(.+)( orders+by| ENDOFSQL)","[,]"));
segments.add(new SqlSegment("(orders+by)(.+)( ENDOFSQL)","[,]"));
}
}
package com.sitinspring.common.sqlparser.single;
import com.sitinspring.common.sqlparser.SqlSegment;
/** *//**
*
* 单句更新语句解析器
* @author 何杨(heyang78@gmail.com)
*
* @since 2009年2月3日9:08:46
* @version 1.00
*/
public class UpdateSqlParser extends BaseSingleSqlParser{
public UpdateSqlParser(String originalSql) {
super(originalSql);
}
@Override
protected void initializeSegments() {
segments.add(new SqlSegment("(update)(.+)(set)","[,]"));
segments.add(new SqlSegment("(set)(.+)( where | ENDOFSQL)","[,]"));
segments.add(new SqlSegment("(where)(.+)( ENDOFSQL)","(and|or)"));
}
}
下面是用于找到具体子类分析器的工厂类:
package com.sitinspring.common.sqlparser.single;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import com.sitinspring.common.sqlparser.exception.NoSqlParserException;
/** *//**
* 单句Sql解析器制造工厂
* @author 何杨(heyang78@gmail.com)
*
* @since 2009-2-3 上午09:45:49
* @version 1.00
*/
public class SingleSqlParserFactory{
public static BaseSingleSqlParser generateParser(String sql){
if(contains(sql,"(insert into)(.+)(select)(.+)(from)(.+)")){
return new InsertSelectSqlParser(sql);
}
else if(contains(sql,"(select)(.+)(from)(.+)")){
return new SelectSqlParser(sql);
}
else if(contains(sql,"(delete from)(.+)")){
return new DeleteSqlParser(sql);
}
else if(contains(sql,"(update)(.+)(set)(.+)")){
return new UpdateSqlParser(sql);
}
else if(contains(sql,"(insert into)(.+)(values)(.+)")){
return new InsertSqlParser(sql);
}
//sql=sql.replaceAll("ENDSQL", "");
throw new NoSqlParserException(sql.replaceAll("ENDOFSQL", ""));
}
/** *//**
* 看word是否在lineText中存在,支持正则表达式
* @param sql:要解析的sql语句
* @param regExp:正则表达式
* @return
*/
private static boolean contains(String sql,String regExp){
Pattern pattern=Pattern.compile(regExp,Pattern.CASE_INSENSITIVE);
Matcher matcher=pattern.matcher(sql);
return matcher.find();
}
}
最后是表示子句的SqlSegment类:
package com.sitinspring.common.sqlparser;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/** *//**
* Sql语句片段
*
* @author 何杨(heyang78@gmail.com)
*
* @since 2009-2-2 下午03:10:29
* @version 1.00
*/
public class SqlSegment{
private static final String Crlf = "n";
private static final String FourSpace = " ";
/** *//**
* Sql语句片段开头部分
*/
private String start;
/** *//**
* Sql语句片段中间部分
*/
private String body;
/** *//**
* Sql语句片段结束部分
*/
private String end;
/** *//**
* 用于分割中间部分的正则表达式
*/
private String bodySplitPattern;
/** *//**
* 表示片段的正则表达式
*/
private String segmentRegExp;
/** *//**
* 分割后的Body小片段
*/
private List<String> bodyPieces;
/** *//**
* 构造函数
* @param segmentRegExp 表示这个Sql片段的正则表达式
* @param bodySplitPattern 用于分割body的正则表达式
*/
public SqlSegment(String segmentRegExp,String bodySplitPattern){
start="";
body="";
end="";
this.segmentRegExp=segmentRegExp;
this.bodySplitPattern=bodySplitPattern;
this.bodyPieces=new ArrayList<String>();
}
/** *//**
* 从sql中查找符合segmentRegExp的部分,并赋值到start,body,end等三个属性中
* @param sql
*/
public void parse(String sql){
Pattern pattern=Pattern.compile(segmentRegExp,Pattern.CASE_INSENSITIVE);
for(int i=0;i<=sql.length();i++){
String shortSql=sql.substring(0, i);
//System.out.println(shortSql);
Matcher matcher=pattern.matcher(shortSql);
while(matcher.find()){
start=matcher.group(1);
body=matcher.group(2);
end=matcher.group(3);
parseBody();
return;
}
}
}
/** *//**
* 解析body部分
*
*/
private void parseBody(){
List<String> ls=new ArrayList<String>();
Pattern p = Pattern.compile(bodySplitPattern,Pattern.CASE_INSENSITIVE);
// 先清除掉前后空格
body=body.trim();
Matcher m = p.matcher(body);
StringBuffer sb = new StringBuffer();
boolean result = m.find();
while (result) {
m.appendReplacement(sb, m.group(0) + Crlf);
result = m.find();
}
m.appendTail(sb);
// 再按空格断行
String[] arr=sb.toString().split("[n]+");
int arrLength=arr.length;
for(int i=0;i<arrLength;i++){
String temp=FourSpace+arr[i];
if(i!=arrLength-1){
temp=temp+Crlf;
}
ls.add(temp);
}
bodyPieces=ls;
}
/** *//**
* 取得解析好的Sql片段
* @return
*/
public String getParsedSqlSegment(){
StringBuffer sb=new StringBuffer();
sb.append(start+Crlf);
for(String piece:bodyPieces){
sb.append(piece+Crlf);
}
return sb.toString();
}
public String getBody() {
return body;
}
public void setBody(String body) {
this.body = body;
}
public String getEnd() {
return end;
}
public void setEnd(String end) {
this.end = end;
}
public String getStart() {
return start;
}
public void setStart(String start) {
this.start = start;
}
}
解析的效果请见:
http://www.blogjava.net/heyang/archive/2009/02/03/253026.html
- ››sql server自动生成批量执行SQL脚本的批处理
- ››sql server 2008亿万数据性能优化
- ››SQL Server 2008清空数据库日志方法
- ››sqlserver安装和简单的使用
- ››SQL Sever 2008 R2 数据库管理
- ››SQL SERVER无法安装成功,sqlstp.log文件提示[未发...
- ››Sql Server中通过父记录查找出所有关联的子记录
- ››SqlServer触发器、存储过程和函数
- ››SQL Server 中的事务(含义,属性,管理)
- ››Sqlite数据库插入和读取图片数据
- ››Sql server 2005拒绝了对对象 'xx表' (数...
- ››Sql server 2005拒绝了对对象 'xx表' (数...
更多精彩
赞助商链接