• 博客园logo
  • 会员
  • 周边
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录

无信不立

  • 博客园
  • 联系
  • 订阅
  • 管理

公告

View Post

【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)词法分析的案例

 /**
     * 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 void test03() {
        String sql = "select name,age,money from tb_order where id=? and status= 2 order by name desc";

        Lexer lexer = new Lexer(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

 

六、一个小案例

/**
     * sql语句的列名=>name
     * sql语句的列名=>age
     * sql语句的列名=>money
     * sql语句的列名=>id
     * sql语句的列名=>status
     * 条件名=>tb_order.id
     * 操作符=>=
     * 值=>123
     * 条件名=>tb_order.status
     * 操作符=>=
     * 值=>2
     * 表名=>tb_order
     */
    public static void test02(){
        String sql = "select name,age,money from tb_order where id=123 and status= 2 order by name desc";
        List<SQLStatement> sqlStatements1=SQLUtils.parseStatements(sql,"mysql");

        SQLStatement sqlStatement=sqlStatements1.get(0);

        SchemaStatVisitor schemaStatVisitor=new SchemaStatVisitor();

        sqlStatement.accept(schemaStatVisitor);

        //获取列信息
        Collection<TableStat.Column> columns=schemaStatVisitor.getColumns();
        for(TableStat.Column column:columns){

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

        }

        //获取条件信息
        List<TableStat.Condition>  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<TableStat.Name, TableStat> 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

 

posted on 2020-12-06 13:36  无信不立  阅读(949)  评论(0)    收藏  举报

刷新页面返回顶部
 
博客园  ©  2004-2026
浙公网安备 33010602011771号 浙ICP备2021040463号-3