druid加载MySQL驱动原理_【mysql】druid数据库连接池之sql解析原理

一、druid的sql解析包含四部分

词法分析器(Lexer)(单词分割,将sql语句中的关键词,标点,用户的相关信息提取出来)

语法分析器(Parser) (形式语言的语法解析,组装语法树)

抽象语法树(AST)(语法树)

语法树访问器(Visitor)对语法树进行遍历访问,采用访问者模式,将数据和行为进行分离的一种设计模式)

二、词法分析器(Lexer)

com.alibaba.druid.sql.parser.Lexer

com.alibaba.druid.sql.dialect.mysql.parser.Lexer

(1)词法分析的token内容

com.alibaba.druid.sql.parser.Token

com.alibaba.druid.sql.parser.Keywords

(2)词法分析的案例

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

/*** SELECT 关键字-select

* IDENTIFIER 标识符

* COMMA 关键字-标点符","

* IDENTIFIER

* COMMA

* IDENTIFIER

* FROM

* IDENTIFIER

* WHERE

* IDENTIFIER

* EQ 关键字-标点符"="

* QUES

* AND

* IDENTIFIER

* EQ

* LITERAL_INT

* ORDER

* BY

* IDENTIFIER

* DESC

* EOF 结束符号,标识sql终结*/

public static voidtest03() {

String sql= "select name,age,money from tb_order where id=? and status= 2 order by name desc";

Lexer lexer= newLexer(sql);for(; ; ) {

lexer.nextToken();

Token token=lexer.token();

System.out.println(token.name());if ("EOF".equals(token.name())) {break;

}

}

}

View Code

三、语法分析器(Parser)

com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser

com.alibaba.druid.sql.parser.SQLStatementParser

com.alibaba.druid.sql.parser.SQLParser

四、抽象语法树(AST)

com.alibaba.druid.sql.ast.statement.SQLSelectStatement  (select语句)

com.alibaba.druid.sql.ast.statement.SQLUpdateStatement  (update语句)

com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlUpdateStatement (update语句)

com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlInsertStatement(insert语句)

com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlDeleteStatement(delete语句)

com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlCreateServerStatement

com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlCreateTableStatement

五、语法树访问器(Visitor)

com.alibaba.druid.sql.visitor.SQLASTVisitor

com.alibaba.druid.sql.visitor.SchemaStatVisitor

六、一个小案例

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

/*** sql语句的列名=>name

* sql语句的列名=>age

* sql语句的列名=>money

* sql语句的列名=>id

* sql语句的列名=>status

* 条件名=>tb_order.id

* 操作符=>=

* 值=>123

* 条件名=>tb_order.status

* 操作符=>=

* 值=>2

* 表名=>tb_order*/

public static voidtest02(){

String sql= "select name,age,money from tb_order where id=123 and status= 2 order by name desc";

List sqlStatements1=SQLUtils.parseStatements(sql,"mysql");

SQLStatement sqlStatement=sqlStatements1.get(0);

SchemaStatVisitor schemaStatVisitor=newSchemaStatVisitor();

sqlStatement.accept(schemaStatVisitor);//获取列信息

Collection columns=schemaStatVisitor.getColumns();for(TableStat.Column column:columns){

System.out.println("sql语句的列名=>"+column.getName());

}//获取条件信息

List conditions=schemaStatVisitor.getConditions();for(TableStat.Condition condition:conditions){

System.out.println("条件名=>"+condition.getColumn());

System.out.println("操作符=>"+condition.getOperator());

System.out.println("值=>"+condition.getValues().get(0));

}//获取表名

Map statMap=schemaStatVisitor.getTables();for(TableStat.Name name:statMap.keySet()){

System.out.println("表名=>"+name.getName());

}

}

View Code

七、语法树节点分类

com.alibaba.druid.sql.ast.SQLObject

com.alibaba.druid.sql.ast.SQLStatement

com.alibaba.druid.sql.ast.SQLExpr

com.alibaba.druid.sql.ast.statement.SQLConstraint

详细描述:https://blog.csdn.net/qq_25104587/article/details/90577646

你可能感兴趣的:(druid加载MySQL驱动原理_【mysql】druid数据库连接池之sql解析原理)