java实现----sql解析器

2023-11-01

更新中!!!!!!

首先我们项目要编写一个小型的dbms。所以我负责编写的sql解析的部分。

所以本文只是记录我学习和编写sql解析器的过程。

----------------------------------------------------------------------------------------------------------------------------------------------

----------------------------------------------------------------------------------------------------------------------------------------------

1.第一阶段:

如果我采用导航模式,可以使用一些split()语句,把sql语句分解出框架部分和内容部分。(这是分析了几个语句的典型模式,采用)“,”和“(”分开的)。针对不同的sql语句,典型的几个select,create,insert,delete都是可以处理的。当然授权,显示都是可以的。但是问题是我必须先让用户选择要执行的步骤是什么,需要用导航,和mysql这种直接输入sql语句,自己去识别的不同。

这个在GitHub中有代码可以参考的。是一个同学的课程设计。我参考了下,他大概思路就是我刚刚说的。


----------------------------------------------------------------------------------------------------------------------------------------------

----------------------------------------------------------------------------------------------------------------------------------------------

2.第二阶段(我就是借鉴他的代码,然后我重新写一个sql_parse)

我们要自己识别,sql语句。所以我网上参考了这个文章。

但是他也明确说,他这个思路是处理单句的sql语句,针对子查询应该是不适用的。

链接:http://www.cnblogs.com/pelephone/articles/sql-parse-single-word.html

他的思路是:

1.预处理。把所有的输入的sql语句,变成标准的形式。处理掉回车,多余的空格部分和特殊字符。规范了大小写。

2.分割成片段:分块+切割;

分块:如何分块?要知道怎么分块,什么是start,body,end;

切割:如何切割?用正则表达式;(具体代码在最后,现在就是知道他的思路是什么)

但是我不知道什么是正则表达式以及它的使用规则也不知道,可以参考:https://www.cnblogs.com/darkterror/p/6474211.html

(而且,如果这么分块到后面是可行并且方便的话,那么编写正则表达式就是一个问题,正则表达式的编写正确将决定分块是否正确)


下面是一个例子,告诉你可以怎么分块:select举例;



----------------------------------------------------------------------------------------------------------------------------------

----------------------------------------------------------------------------------------------------------------------------------------------


正则表达式的符号使用规则:

https://www.cnblogs.com/darkterror/p/6474211.html

正则表达式中:()和 | 的作用;



----------------------------------------------------------------------------------------------------------------------------------

----------------------------------------------------------------------------------------------------------------------------------------------

3.根据提取中的各个块,我们要其中的body部分。然后对其中的body进行处理,然后给底层传参就可以了。

在没看代码的时候我有两个问题:

        第一,如何把一个sql分块成不同的部分

        第二,怎么提取body中的各个有效部分;

下面的代码将依次解答这个问题,并且会粘贴最核心的代码与分析过程;

----------------------------------------------------------------------------------------------------------------------------------------------

----------------------------------------------------------------------------------------------------------------------------------------------

       如何把一个sql分块成不同的部分?

分析:segmentRegExp为自己写的正则表达式(用于切割);循环是从sql的第一个位置开始遍历的,一次增加一个index,用segmentRegExp去匹配shortSql,matcher.find()返回的结果是boolean,如果找到了匹配的结果,就进入while中进行赋值;我们的正则表达式是(start)(body)(end)三个不部分的,因此我们的matcher.group(int<=3).

(这是他代码的解决部分,针对这部分我进行了升级和简化。代码再后面)

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);// 片段起始标志start
  body=matcher.group(2);// 片段主体body
  end=matcher.group(3);// 片段结束标志end
  parseBody();
  return;
   }

 }


注意:

    1.为什么要从最开始去遍历?

        我参考的文章的解释是:因为如果直接用sql与我们的正则表达式segmentRegExp匹配的话,那么他属于贪婪匹配,他会尽可能的往后找,就是找到where后还会继续往后找,看有没有 on | having | groups+by | orders+by | ENDOFSQL等。所以他找到的结果不会在我们想要的where处停止。因此需要从sql的第一个字符处去遍历,这样找到where处就停止了。

但是我测试了他给的代码,结果是并不会停止。就像下面我的图片一样,所以我就去查了正则表达式关于贪婪和不贪婪的问题,我发现他贪婪不是因为我们【|||】中的“|”导致的,而是因为包含重复限定符的时候才会出现贪婪的情况,可是|不算重复的限定符吧?而下面的几个字符才算是重复的限定字符吧?(这也是我的一个疑问。有知道的朋友请留言告知,谢谢!)因此问题应该出在了前面的(.+)上面。

然后我的解决办法是,使用+?符号。(开始我以为只是?的作用)但是后来我查了下,+?是重复一次或者多次,但是是尽可能的少,因此他就可以匹配到where就结束了。

同时,我个人认为,如果加了+?就可以解决贪婪的问题,那么我们是不是不需要在从头开始遍历了,只需要直接匹配就可以了,我改完全部的代码,会回头解释这个问题的。

经过我的测试,完全不用从头遍历,加一个?就会解决贪婪遍历的问题,代码在最后。



    2.什么时候会进入到while循环中,也就是matcher.find()什么时候为true?

        如果我的正则表达式是(start)(body)(end)那么只有当这三个部分全部被匹配一次的时候,才返回true。如果只匹配了一个start部分是不会显示匹配成功的。

例如:

   sql:select name from table_name where id=2 order by name;

   segmentRegExp: "(from)(.+)( where | on | having | groups+by | orders+by | ENDOFSQL)"


输出结果为:结果是从查到where后就进入到了while循环;

 

        ……………………省略…………………………


    如果让匹配停止在where就不进行了。我的处理代码和输出结果:

segments.add(new SqlSegment("(from)(.+?)( where |  having | group\\s+by | order\\s+by | ENDOFSQL)","(,|s+lefts+joins+|s+rights+joins+|s+inners+joins+)"));


输出代码是:他会停止在where部分。

输出的分别为,sql语句;start部分;body部分;end部分;


参考:https://blog.csdn.net/wzygis/article/details/43339241


代码优化:


public void parse(String sql)
{
//进行测试(测试分块程序是否正确,该代码为正确的,现要测试一共分块了几次,结果都为什么?
//-----------------------------------------------------------------------------------------------------------

// System.out.println();
// System.out.println("开始对sql进行分块");
// System.out.println("分块");
//-----------------------------------------------------------------------------------------------------------

Pattern pattern=Pattern.compile(segmentRegExp,Pattern.CASE_INSENSITIVE);
Matcher matcher=pattern.matcher(sql);
while(matcher.find())
{
start=matcher.group(1);
body=matcher.group(2);
end=matcher.group(3);
// System.out.println(start);
// System.out.println(body);
// System.out.println(end);
// System.out.println();
parseBody();

}

}

---------------------------------------------------------------------------------------------------------------------------------------------

----------------------------------------------------------------------------------------------------------------------------------------------

matcher.group()介绍:


输出结果:


参考:https://www.cnblogs.com/jsStudyjj/p/6145623.html

----------------------------------------------------------------------------------------------------------------------------------------------

----------------------------------------------------------------------------------------------------------------------------------------------

提取出的body部分怎么处理呢?

就是根据正则表达式把body部分分开,分开的部分放在List中。我把start添加到bodyPiece中是因为,我要判断类似select这种语句后面是否有where这种可选语句,有的话有什么,因此我需要保留start部分,然后传给后面。

代码部分:


/** *//**
	 * 解析body部分
	 *
	 */
	private void  parseBody()
	{
		//System.out.println("分body");
		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();
//---------------------------------------------------------------------------------------------------------------------------
	//测试下group(0)是什么,他怎么进行替换的?
//		if(result)
//		{
//			System.out.println(m.group(0));
//		}
//---------------------------------------------------------------------------------------------------------------------------
		while (result) 
		{
			m.appendReplacement(sb,Crlf);
			result = m.find();
		}
		m.appendTail(sb);
//---------------------------------------------------------------------------------------------------------------------------
//		System.out.println(sb.toString());
//---------------------------------------------------------------------------------------------------------------------------		
		// 再按空格断行
		ls.add(start);
		String[] arr=sb.toString().split("[|]");
		int arrLength=arr.length;
		for(int i=0;i<arrLength;i++)
		{
//			System.out.println(arr[i]);
//			String temp=FourSpace+arr[i];
//			System.out.println(temp);
			ls.add(arr[i]);
		}
		bodyPieces = ls;
	
	}

下面粘贴代码:

这是目录:


                                    

SqlSegment.java


package com.sitinspring.common.sqlparser.single;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/** *//**
* Sql语句片段
* @since 2018-4-4 
*/
public class SqlSegment {
	private static final String Crlf = "|";
	@SuppressWarnings("unused")
	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)
	{
		//进行测试(测试分块程序是否正确,该代码为正确的,现要测试一共分块了几次,结果都为什么?
//-----------------------------------------------------------------------------------------------------------
		
//		System.out.println();
//		System.out.println("开始对sql进行分块");
//		System.out.println("分块");
//-----------------------------------------------------------------------------------------------------------
		
		Pattern pattern=Pattern.compile(segmentRegExp,Pattern.CASE_INSENSITIVE);
		Matcher matcher=pattern.matcher(sql);
		while(matcher.find())
		{
			start=matcher.group(1);
			body=matcher.group(2);
			end=matcher.group(3);
//			System.out.println(start);
//			System.out.println(body);
//			System.out.println(end);
//			System.out.println();
			parseBody();
			
		}
		
		//根本不需要通过遍历sql来检测分块部分。
//		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);
-----------------------------------------------------------------------------------------------------------
				  System.out.println(start);
					System.out.println(body);
					System.out.println(end);
					System.out.println();
-----------------------------------------------------------------------------------------------------------
//					
//				//调用解析body部分
//				parseBody();
//			
//			
//			}
//			
//		}
		
	}
	
	/** *//**
	 * 解析body部分
	 *
	 */
	private void  parseBody()
	{
		//System.out.println("分body");
		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();
//---------------------------------------------------------------------------------------------------------------------------
	//测试下group(0)是什么,他怎么进行替换的?
//		if(result)
//		{
//			System.out.println(m.group(0));
//		}
//---------------------------------------------------------------------------------------------------------------------------
		while (result) 
		{
			m.appendReplacement(sb,Crlf);
			result = m.find();
		}
		m.appendTail(sb);
//---------------------------------------------------------------------------------------------------------------------------
//		System.out.println(sb.toString());
//---------------------------------------------------------------------------------------------------------------------------		
		// 再按空格断行
		ls.add(start);
		String[] arr=sb.toString().split("[|]");
		int arrLength=arr.length;
		for(int i=0;i<arrLength;i++)
		{
//			System.out.println(arr[i]);
//			String temp=FourSpace+arr[i];
//			System.out.println(temp);
			ls.add(arr[i]);
		}
		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 getStart() {
		return start;
	}

	public void setStart(String start) {
		this.start = start;
	}

	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 getBodySplitPattern() {
		return bodySplitPattern;
	}

	public void setBodySplitPattern(String bodySplitPattern) {
		this.bodySplitPattern = bodySplitPattern;
	}

	public String getSegmentRegExp() {
		return segmentRegExp;
	}

	public void setSegmentRegExp(String segmentRegExp) {
		this.segmentRegExp = segmentRegExp;
	}

	public List<String> getBodyPieces() {
		return bodyPieces;
	}

	public void setBodyPieces(List<String> bodyPieces) {
		this.bodyPieces = bodyPieces;
	}
	
}
BaseSingleSqlParser:

package com.sitinspring.common.sqlparser.single;

import java.util.ArrayList;
import java.util.List;

public abstract class BaseSingleSqlParser {
	
	//原始Sql语句
	protected String originalSql;

	//Sql语句片段
	protected List<SqlSegment> segments;
	
	
	/** *//**
	 * 构造函数,传入原始Sql语句,进行劈分。
	 * @param originalSql
	 */
	public BaseSingleSqlParser(String originalSql)
	{
		//System.out.println("调用了BaseSingleSqlParser的构造函数");
		this.originalSql=originalSql;
		segments=new ArrayList<SqlSegment>();
		initializeSegments();
		//splitSql2Segment();
	}
	
	/** *//**
	 * 初始化segments,强制子类实现
	 *
	 */
	protected abstract void initializeSegments();
	
	
	/** *//**
	 * 将originalSql劈分成一个个片段
	 *
	 
	 * @return */
	protected List<List<String>> splitSql2Segment() 
	{
		List<List<String>> list=new ArrayList<List<String>>(); 
		
		//System.out.println("调用了BaseSingleSqlParser的splitSql2Segment方法,用于分割sql为不同的模块");
		for(SqlSegment sqlSegment:segments)    // int[] aaa = 1,2,3;   int a:aaa 
		{
			sqlSegment.parse(originalSql);
			list.add(sqlSegment.getBodyPieces());
		}	
		return list;
	}
	
	/** *//**
	 * 得到解析完毕的Sql语句
	 * @return
	 */
	public String getParsedSql() 
	{
		StringBuffer sb=new StringBuffer();
		for(SqlSegment sqlSegment:segments)
		{
			sb.append(sqlSegment.getParsedSqlSegment()+"n");
		}
		String retval=sb.toString().replaceAll("n+", "n");
		return retval;
	}
	
}

SingleSqlParserFactory:

package com.sitinspring.common.sqlparser.single;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

//test-success
// throws Exception
public class SingleSqlParserFactory 
{
	
	public static List<List<String>> generateParser(String sql)
	{
		BaseSingleSqlParser tmp = null;
		
		if(contains(sql,"(insert into)(.+)(select)(.+)(from)(.+)"))
		{
			System.out.println("insert_select");
			tmp = new InsertSelectSqlParser(sql);
			//return tmp.splitSql2Segment();
		}
		else if(contains(sql,"(select)(.+)(from)(.+)"))
		{
			
			System.out.println("select");
			tmp = new SelectSqlParser(sql);
			//System.out.println("初始化SelectSqlParser结束");
		}
		else if(contains(sql,"(delete from)(.+)"))
		{
			System.out.println("delete");
			tmp = new DeleteSqlParser(sql);
			//return new DeleteSqlParser(sql);
		}
		else if(contains(sql,"(update)(.+)(set)(.+)"))
		{
			System.out.println("update");
			tmp = new UpdateSqlParser(sql);
			//return new UpdateSqlParser(sql);
		}
		else if(contains(sql,"(insert into)(.+)(values)(.+)"))
		{
			System.out.println("insert");
			tmp = new InsertSqlParser(sql);
			//return new InsertSqlParser(sql);
		}
		else if(contains(sql,"(create table)(.+)"))
		{
			System.out.println("create table");
		 // return new InsertSqlParser(sql);
		}
		else if(contains(sql,"(create database)(.+)"))
		{
			System.out.println("create database");
		// return new InsertSqlParser(sql);
		}
		else if(contains(sql,"(show databases)"))
		{
			System.out.println("show databases");
		// return new InsertSqlParser(sql);
		}
		else if(contains(sql,"(use)(.+)"))
		{
			System.out.println("use");
		// return new InsertSqlParser(sql);
		}
		else 
			{
				System.out.println("Input errors, please re-enter");
			}
		//sql=sql.replaceAll("ENDSQL", "");
	//	throw new Exception(sql.replaceAll("ENDOFSQL", ""));
		//return null;
		
		return tmp.splitSql2Segment();
	}
		/** *//**
		 * 看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();
		}
	}

DeleteSqlParser.java:

package com.sitinspring.common.sqlparser.single;

/** *//**
*
* 单句删除语句解析器
*/
//正确
public class DeleteSqlParser extends BaseSingleSqlParser 
{

	
	public DeleteSqlParser(String originalSql) {
		super(originalSql);
		
	}
	
	//delete from table_name where ();
	
	@Override
	protected void initializeSegments() {
		//System.out.println("调用了DeleteSqlParser的initializeSegments方法");
		segments.add(new SqlSegment("(delete from)(.+)( where | ENDOFSQL)","[,]"));
		segments.add(new SqlSegment("(where)(.+)( ENDOFSQL)","(and|or)"));
		}
		
}


UpdateSqlParser.java:


package com.sitinspring.common.sqlparser.single;

//正确
public class UpdateSqlParser extends BaseSingleSqlParser{

	public UpdateSqlParser(String originalSql) {
		super(originalSql);
		
	}

	//update(table_name) set (key = value) where();
	
	@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)"));
	}

}

SelectSqlParser.java

package com.sitinspring.common.sqlparser.single;
/** *//**
*
* 单句查询语句解析器
*/
//正确
public class SelectSqlParser extends BaseSingleSqlParser{

	public SelectSqlParser(String originalSql) 
	{
		super(originalSql);
		
	}

	@Override
	protected void initializeSegments()
	{
		System.out.println("调用了SelectSqlParser的initializeSegments方法,用于初始化正则表达式语句");
		segments.add(new SqlSegment("(select)(.+)(from)","[,]"));
		segments.add(new SqlSegment("(from)(.+?)(where |group\\s+by|having|order\\s+by | ENDOFSQL)","(,|s+lefts+joins+|s+rights+joins+|s+inners+joins+)"));
		segments.add(new SqlSegment("(where)(.+?)(group\\s+by |having| order\\s+by | ENDOFSQL)","(and|or)"));
		segments.add(new SqlSegment("(group\\s+by)(.+?)(having|order\\s+by| ENDOFSQL)","[,]"));
		segments.add(new SqlSegment("(having)(.+?)(order\\s+by| ENDOFSQL)","(and|or)"));
		segments.add(new SqlSegment("(order\\s+by)(.+)( ENDOFSQL)","[,]"));
		
	}

}

InsertSelectSqlParser.java

package com.sitinspring.common.sqlparser.single;
/** *//**
*
* 单句查询插入语句解析器
*/
//正确-test
public class InsertSelectSqlParser extends BaseSingleSqlParser {

	public InsertSelectSqlParser(String originalSql) {
		super(originalSql);
		
	}
	
	//select () from table_name where () order by () having () group by () limit();
	
	@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)","[,]"));
		}
		
}



InsertSqlParser.java

package com.sitinspring.common.sqlparser.single;
/** *//**
*
* 单句插入语句解析器
*/
//correct-test
public class InsertSqlParser extends BaseSingleSqlParser{

	public InsertSqlParser(String originalSql) {
		super(originalSql);
		
	}
	//insert into table_name (name,age,sex) values ("小明","28","女");
	@Override
	protected void initializeSegments() {
		segments.add(new SqlSegment("(insert into)(.+?)([(])","[,]"));
		segments.add(new SqlSegment("([(])(.+?)([)] values [(])","[,]"));
		segments.add(new SqlSegment("([)] values [(])(.+)([)] ENDOFSQL)","[,]"));
		// values
	}
	
	public String getParsedSql()
	{
		String retval=super.getParsedSql();
		retval=retval+")";
		return retval;
	}
		
}

Test.java 主类

package com.sitinspring.common.sqlparser.single;

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;


public class Test {
	public static void main (String arg[])
	{
		System.out.println("欢迎您登录登录,请开始使用。");
		/*
		 * 应该有一个验证管理员和用户的功能。
		 */
		System.out.println("请出入sql语句");
		boolean temp = true;
		while(temp)
		{
			@SuppressWarnings("resource")
			Scanner input = new Scanner(System.in);
			String sql = input.nextLine();
			/*
			 * 预处理:获得语句;
			 * 处理前后空格;
			 * 变小写;
			 * 处理中间多余的空格回车和特殊字符;
			 * 在末尾加特殊符号;
			 * 处理掉最后的;
			 */
			
			//处理分行输入的问题,就是读;号才停止;
			while(sql.lastIndexOf(";")!=sql.length()-1){
				sql = sql+" "+input.nextLine();
			}
			
			sql = sql.trim();
			sql=sql.toLowerCase();
			sql=sql.replaceAll("\\s+", " ");
			
			sql = sql.substring(0, sql.lastIndexOf(";"));
			sql=""+sql+" ENDOFSQL";
			System.out.println(sql);
			
			/*
			 * 结束输入判断
			 */
//			Pattern pattern=Pattern.compile("(quit)");
//			Matcher matcher=pattern.matcher(sql);
//			System.out.println(matcher.find());
			@SuppressWarnings("unused")
			List<List<String>> parameter_list=new ArrayList<List<String>>(); 
			
			if(sql.equals("quit"))
			{
				temp = false;
			}
			else
			{
				//System.out.println("准备执行SingleSqlParserFactory.generateParser函数");
				/*
				 * 工厂类判断调用什么语句的正则表达分割
				 */
				parameter_list = SingleSqlParserFactory.generateParser(sql);
//----------------------------------------------------------------------------------------------------------------
				System.out.println("执行结束SingleSqlParserFactory.generateParser函数");
				
				for(int i = 0;i < parameter_list.size();i++)
				{
					System.out.println(parameter_list.get(i));
				}
				
//				System.out.println();
//				
//				List<String> test = new ArrayList<String>();
//				test = parameter_list.get(2);
//				
//				for(int i = 0;i < test.size();i++)
//				{
//					String r = test.get(i);
//					System.out.println(r.trim());
//				}
//----------------------------------------------------------------------------------------------------------------
			}
	
			
		}
		
	}
}

现在,在我完成了sql的编写好,我的下一个问题是,如果方便的传参然后调用每个功能模块!!!!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

java实现----sql解析器 的相关文章

随机推荐

  • 内存分页

    内存分页 p Description 内存分页 p param records 待分页的数据 param pageNum 当前页码 param pageSize 每页显示的条数 return 分页之后的数据 public static
  • Git——C站最详细的Git教程,一篇学会Git(window\linux通用)

    Git C站最详细的Git教程 一篇学会Git window linux通用 文章目录 Git C站最详细的Git教程 一篇学会Git window linux通用 Git简介 Git 作用 为什么要进行源代码管理 Git的诞生 Git管理
  • vue双向数据绑定指令v-model

    vue双向数据绑定指令v model v model 被称为双向数据绑定指令 就是Vue实例对数据进行修改 页面会立即感知 相反页面对数据进行修改 Vue内部也会立即感知 v model 是vue中唯一实现双向数据绑定的指令 v bind
  • mybatis增删改查的写法集合

    增删改查的写法集合 注意 xml文件尽量不要注释 Usermapping public interface UserMapping 查询 List
  • mysql建_mysql简单建表

    NULL 和 NOT NULL 修饰符 可以在每个字段后面都加上这NULL 或 NOT NULL 修饰符来指定该字段是否可以为空 NULL 还是说必须填上数据 NOT NULL MySQL默认情况下指定字段为NULL修饰符 如果一个字段指定
  • 《Kafka系列》Java测试远程连接Kafka,实现生产者和消费者,发现两者数据不通?

    Java测试远程连接Kafka 实现生产者和消费者 发现两者数据不通 错误显示 错误排除 1 在网上看到有这种方法 修改Kafka下的conf下的server properties文件 cd opt apps kafka conf serv
  • Stream流

    概念 是JDK1 8的新语法 和IO流不是一个东西相当于流水线 很方便的对数据进行加工 Stream流把真正的函数式编程风格引入到Java中 代码简洁 Stream流不能直接修改数据源中的数据 不使用Stream流的优势是加工处理数据 每个
  • buuctf_Exec

    0x01 题目链接 BUUCTF在线评测BUUCTF 是一个 CTF 竞赛和训练平台 为各位 CTF 选手提供真实赛题在线复现等服务 https buuoj cn challenges 0x02 题目 打开题目就看到大大的PING 二话不说
  • 在存储过程中使用了DML语句要不要调用COMMIT?

    要调用commit语句 或者正常退出sqlplus 系统会自动提交 dml语句不能自动提交 ddl语句和dcl语句可以自动提交 转自 http bbs csdn net topics 80160481
  • 胶囊体阴影

    官方介绍 虚幻引擎现在支持非常柔滑的间接阴影 由代表角色的胶囊体来进行投影 通常 在受间接光照时 并不会产生阴影 除非是屏幕空间环境遮罩 间接投影需要做的非常柔滑 因为间接光照是来自很多不同的方向 因此 传统的阴影贴图做法的效果并不好 间接
  • android windows 安装

    转自 http www cnblogs com skynet archive 2010 04 12 1709892 html 本系列适合0基础的人员 因为我就是从0开始的 此系列记录我步入Android开发的一些经验分享 望与君共勉 作为A
  • 安防监控视频云存储平台EasyNVR通道频繁离线的原因排查与解决

    安防视频监控汇聚EasyNVR视频集中存储平台 是基于RTSP Onvif协议的安防视频平台 可支持将接入的视频流进行全平台 全终端分发 分发的视频流包括RTSP RTMP HTTP FLV WS FLV HLS WebRTC等格式 为了满
  • MATLAB神经网络编程(四)——线性神经网络的实现与局限

    MATLAB神经网络编程 化学工业出版社 读书笔记 第四章 前向型神经网络 4 2 线性神经网络 本文是 MATLAB神经网络编程 书籍的阅读笔记 其中涉及的源码 公式 原理都来自此书 若有不理解之处请参阅原书 一 线性神经网络的实现 线性
  • vue 中 elementui Dropdown 下拉菜单中 选项的click事件

  • gcc/g++交叉编译*.c/*.cpp程序时的配置

    CFLAGS I PWD src CFLAGS I third party hisi include CFLAGS L third party hisi lib CXXFLAGS I PWD src CXXFLAGS I third par
  • 电脑网络故障:LSP造成?

    问题 1 什么是LSP 删除了什么才导致了不能上网 LSP 为什么能影响网络 其内部的原理机制是什么 网络连接正常但无法上网 能ping通外网DNS 解决方法 2013 11 03 00 47 17 转载 标签 辅助工具 在线聊天 解决方法
  • java 阻塞模式与非阻塞模式

    TCP IP 阻塞模式与非阻塞模式 java view plain copy print package concurrentTest import java io BufferedReader import java io IOExcep
  • warning:Deprecated declaration LaberPwmSel_High - give arg types解决方法

    有些小伙伴在编译代码的时候偶尔会遇到这样的警告 当然这对整体并没有什么影响 直接忽略也是ok的 警告的大概意思是 LaberPwmSel High 应该提供类型声明 也就是说 使用MDK编译器的时候 如果函数在定义时没有传参 要在括号中加v
  • css禁止滑动页面_css页面滑动穿透的两种解决办法

    这篇文章主要介绍了css如何防止页面滑动穿透 小编觉得挺不错的 现在分享给大家 也给大家做个参考 一起跟随小编过来看看吧 问题描述 移动端当有 fixed 遮罩背景和弹出层时 在屏幕上滑动能够滑动背景下面的内容 这就是著名的滚动穿透问题 示
  • java实现----sql解析器

    更新中 首先我们项目要编写一个小型的dbms 所以我负责编写的sql解析的部分 所以本文只是记录我学习和编写sql解析器的过程