mycat sql解析
2019-06-19 本文已影响0人
布衣小菜
mycat借助于druid提供的sql解析工具,把client端传入的sql语句解析成一棵AST语法树
AST语法树如下所示:
image.png
example1:
select * from table1 where c1 = 100 order by id desc, name asc limit 0, 10
解析后可以获得如下信息:
from table: table1
select list:[*]
where: c1 (Equality) 100
order by: id DESC
order by: name ASC
limit: offset = 0 count = 10
example2:
select c1, c2, c3 from table1 where c1 = 'v1' and c2 >= 100 order by id desc limit 0, 10
解析后可以获得如下信息:
from table: table1
select list:[c1, c2, c3]
where: c1 = 'v1' (BooleanAnd) c2 >= 100
order by: id DESC
limit: offset = 0 count = 10
另外还可以针对函数场景,多表join场景,带子查询场景,select-for-update等多种场景进行解析,功能非常强大,而且性能上似乎也比较快
使用之前需要在pom中增加对druid包的依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.11</version>
</dependency>
使用demo
public static void selectParse(String sql) {
System.out.println("start parse sql:" + sql);
MySqlStatementParser parser = new MySqlStatementParser(sql);
SQLSelectStatement statement = (SQLSelectStatement) parser.parseStatement();
SQLSelectQuery query = statement.getSelect().getQuery();
if (query instanceof MySqlSelectQueryBlock) {
MySqlSelectQueryBlock queryBlock = (MySqlSelectQueryBlock) query;
System.out.println("from table:" + queryBlock.getFrom());
System.out.println("select list:" + queryBlock.getSelectList());
//System.out.println("where: " + queryBlock.getWhere());
//System.out.println(queryBlock.getWhere().getClass().getName());
SQLBinaryOpExpr where = (SQLBinaryOpExpr) queryBlock.getWhere();
if (where != null) {
System.out.println("where: " + where.getLeft() + " (" + where.getOperator() + ") " + where.getRight());
}
SQLOrderBy orderBy = queryBlock.getOrderBy();
if (orderBy != null) {
for (SQLSelectOrderByItem item : queryBlock.getOrderBy().getItems()) {
System.out.println("order by:" + item.getExpr() + " " + item.getType());
}
}
MySqlSelectQueryBlock.Limit limit = queryBlock.getLimit();
if (limit != null) {
System.out.println("limit: offset = " + limit.getOffset() + " count = " + limit.getRowCount());
}
}
System.out.println();
}