内容简介:上一篇文章我们分析了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源码解析
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
ACM/ICPC程序设计与分析
沈云付 / 清华大学 / 2010-7 / 39.50元
《ACM/ICPC程序设计与分析(C++实现)》介绍ACM国际大学生程序设计竞赛概况及程序设计基础,系统介绍数论、组合数学、动态规划、计算几何、搜索、图论和网络流等专题的典型算法,挑选历年竞赛中许多有代表性的竞赛题作为例题进行分析,便于学生编程时模仿学习。每章的例题和习题都配有输入输出样例,方便学生在编程时测试与调试程序。《ACM/ICPC程序设计与分析(C++实现)》以C++为程序设计语言,以提......一起来看看 《ACM/ICPC程序设计与分析》 这本书的介绍吧!