内容简介:上一篇文章我们分析了sql词法解析,主要讲了sql是如何被解析为一个一个的单词的,在这个基础上,我们来看看sharding-jdbc是如何针对不同的DML语句来识别sql语法,提取表结构信息的。SQL解析的入口,主要方法是parse(),1、根据入参
上一篇文章我们分析了 sql 词法解析,主要讲了sql是如何被解析为一个一个的单词的,在这个基础上,我们来看看sharding-jdbc是如何针对不同的DML语句来识别sql语法,提取表结构信息的。
相关类简要说明
- SQLParsingEngine:解析SQL的入口,分析不同的SQL(SELECT,UPDATE etc),不同的SQLParser(MySQLParser etc),实例化不同的解析类(MySQLSelectParser etc).
- SQLParser:SQL解释器,分析SQL中表名称、别名、列名称、表达式等,填充到具体的对象;不同的数据库有不同的实现。
- SQLStatementParser:SQL解析器的父类,AbstractSelectParser、AbstractInsertParser、AbstractSelectParser、AbstractUpdateParser是其实现(每个数据库又有不同的实现,例如:MySQLSelectParser就是AbstractSelectParser的实现),对于parse()方法,子类有不同的实现;通过调用SQLParser中的方法,分析SQL语句
- SQLStatement:SQL语句的最终解析对象,主要有Table、Conditions(SQL的条件)、Column;不同的DML语句有不同的实现
- SQLExpression:SQL表达式,分析where语句后的表达式,主要有标识、数字、属性、占位符等表达式
时序图
1、SQLParsingEngine
SQL解析的入口,主要方法是parse(),
1、根据入参 dbType 实例化具体的 SQLParser
2、根据sqlParser分析sql语义(是哪种类型的sql),实例化对应的解析类
/**
* 解析SQL.
*
* @return SQL语句对象
*/
public SQLStatement parse() {
SQLParser sqlParser = getSQLParser();
sqlParser.skipIfEqual(Symbol.SEMI);
if (sqlParser.equalAny(DefaultKeyword.WITH)) {
skipWith(sqlParser);
}
if (sqlParser.equalAny(DefaultKeyword.SELECT)) {
return SelectParserFactory.newInstance(sqlParser).parse();
}
if (sqlParser.equalAny(DefaultKeyword.INSERT)) {
return InsertParserFactory.newInstance(shardingRule, sqlParser).parse();
}
if (sqlParser.equalAny(DefaultKeyword.UPDATE)) {
return UpdateParserFactory.newInstance(sqlParser).parse();
}
if (sqlParser.equalAny(DefaultKeyword.DELETE)) {
return DeleteParserFactory.newInstance(sqlParser).parse();
}
throw new SQLParsingUnsupportedException(sqlParser.getLexer().getCurrentToken().getType());
}
复制代码
以SelectParserFactory为例:
/**
* 创建Select语句解析器.
*
* @param sqlParser SQL解析器
* @return Select语句解析器
*/
public static AbstractSelectParser newInstance(final SQLParser sqlParser) {
if (sqlParser instanceof MySQLParser) {
return new MySQLSelectParser(sqlParser);
}
if (sqlParser instanceof OracleParser) {
return new OracleSelectParser(sqlParser);
}
if (sqlParser instanceof SQLServerParser) {
return new SQLServerSelectParser(sqlParser);
}
if (sqlParser instanceof PostgreSQLParser) {
return new PostgreSQLSelectParser(sqlParser);
}
throw new UnsupportedOperationException(String.format("Cannot support sqlParser class [%s].", sqlParser.getClass()));
}
复制代码
2、SQLParser:
SQL解析器,主要用来解析SQL语句对象,不同的数据库有不同的实现
/**
* 解析单表.
*
* @param sqlStatement SQL语句对象
*/
public final void parseSingleTable(final SQLStatement sqlStatement) {
...//省略
sqlStatement.getTables().add(table);
}
/**
* 解析表达式.
*
* @param sqlStatement SQL语句对象
* @return 表达式
*/
public final SQLExpression parseExpression(final SQLStatement sqlStatement) {
int beginPosition = getLexer().getCurrentToken().getEndPosition();
SQLExpression result = parseExpression();
if (result instanceof SQLPropertyExpression) {
setTableToken(sqlStatement, beginPosition, (SQLPropertyExpression) result);
}
return result;
}
/**
* 解析查询条件.
*
* @param sqlStatement SQL语句对象
*/
public final void parseWhere(final SQLStatement sqlStatement) {
parseAlias();
if (skipIfEqual(DefaultKeyword.WHERE)) {
parseConditions(sqlStatement);
}
}
复制代码
3、SQLStatementParse
SQL语句解释器,不同的DML语句有不同的实现,不同的数据库也有不同的实现;来看张实现截图:
为例:
private final SQLParser sqlParser;
private final SelectStatement selectStatement;
复制代码
这是2个重要参数;通过调用SQLParser中的方法分析sql语句的表结构,然后构造SelectStatement返回
@Override
public final SelectStatement parse() {
query();
parseOrderBy();
customizedSelect();
appendDerivedColumns();
appendDerivedOrderBy();
return selectStatement;
}
复制代码
4、SQLStatement:
SQL最终解析后的对象,不同的DML语句有不同的实现,来看下实现截图:
以SELECT语句为例,来看看都有哪些参数:
private boolean distinct;
private boolean containStar;
private int selectListLastPosition;
private int groupByLastPosition;
private final List<SelectItem> items = new LinkedList<>();
private final List<OrderItem> groupByItems = new LinkedList<>();
private final List<OrderItem> orderByItems = new LinkedList<>();
private Limit limit;
public SelectStatement() {
super(SQLType.SELECT);
}
复制代码
好了,今天我们整体上看下SQL解析过程中用的类,以及主要的方法,下面一篇文章我们将分析SELECT语句是怎么被解析的
最后
小尾巴走一波,欢迎关注我的公众号,不定期分享编程、投资、生活方面的感悟:)
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- ReactNative源码解析-初识源码
- Spring源码系列:BeanDefinition源码解析
- Spring源码分析:AOP源码解析(下篇)
- Spring源码分析:AOP源码解析(上篇)
- 注册中心 Eureka 源码解析 —— EndPoint 与 解析器
- 新一代Json解析库Moshi源码解析
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Parsing Techniques
Dick Grune、Ceriel J.H. Jacobs / Springer / 2010-2-12 / USD 109.00
This second edition of Grune and Jacobs' brilliant work presents new developments and discoveries that have been made in the field. Parsing, also referred to as syntax analysis, has been and continues......一起来看看 《Parsing Techniques》 这本书的介绍吧!