使用Druid解析SQL小试
这是学习笔记的第 1862篇文章
Druid在行业内是一个很流行的开源工具,在很多开发项目里的数据源选型都是它,按照官方的参考数据,Druid的性能非常好,都是纳秒级别。
GitHub上Druid的星有一万多,光提交的issue就有1000多个,可见在社区里面也算是久经沙场了。
Druid和开发方向关系比较紧密,和DBA方向有什么关系呢。其实还是回归到本质,和SQL有关,在SQL方向目前存在几个瓶颈。
行业内的审核工具对于DML的支持很有限。
开源工具和数据库的绑定比较紧,不够通用,难以实现SQL方言化解析.
语法和词法分析是一个技术活,单纯分析文本做解析简单粗暴,没有体系化就难以实现扩展。
鉴于目前MySQL方向走得快一些,其他方向的事务性工作依旧繁琐,所以我希望在已有的基础上做一个大的改变,那就是SQL审核2.0版本,通过提供通用的技术体系来支撑通用的数据库规范。
Druid不光作为一个通用的数据源性能优越,而且里面也内置了大量的辅助功能。 其实看到Druid实现的demo,会发现它早已超出了本身的定位,可以做一些监控和优化,还有SQL解析器。
我们可以完全站在巨人的肩膀上,把这些信息继承起来,然后融入我们自定义的逻辑来满足当前的业务需求。
如果你不熟悉Java,按照GitHub的方式来编译Druid,这应该会是一个不好的开始。
因为摆在你面前的第一道门槛就是maven,其实maven就是一个档案库,我们可以从里面提取得到相关的软件。对于maven,就类似于我们使用yum的方式是类似的。
我们要创建一个java项目,以maven的方式创建。
在pom.xml引入如下的依赖即可。
<dependencies>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.10</version>
</dependency>
</dependencies>
新建一个Java文件,代码类似下面的形式。
import java.util.List;
import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.ast.SQLStatement;
import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlSchemaStatVisitor;
import com.alibaba.druid.util.JdbcConstants;
/**
* Hello world!
*
*/
public class Test {
public static void main(String[] args) {
//String sql = "update t set name = 'x' where id < 100 limit 10";
// String sql = "SELECT ID, NAME, AGE FROM USER WHERE ID = ? limit 2";
// String sql = "select * from tablename limit 10";
String sql = "CREATE TABLE `define_cdetag` (\n" +
" `id` int(32) unsigned NOT NULL COMMENT '配置项使用时标识',\n" +
" `thiSection` varchar(32) DEFAULT NULL COMMENT 'StageID白名单区间',\n" +
" `thiExceptList` text COMMENT 'test名单列表',\n" +
" PRIMARY KEY (`id`)\n" +
") ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='test';";
String dbType = JdbcConstants.MYSQL;
//格式化输出
String result = SQLUtils.format(sql, dbType);
System.out.println(result); // 缺省大写格式
List<SQLStatement> stmtList = SQLUtils.parseStatements(sql, dbType);
//解析出的独立语句的个数
System.out.println("size is:" + stmtList.size());
for (int i = 0; i < stmtList.size(); i++) {
SQLStatement stmt = stmtList.get(i);
MySqlSchemaStatVisitor visitor = new MySqlSchemaStatVisitor();
stmt.accept(visitor);
//获取表名称
//System.out.println("Tables : " + visitor.getCurrentTable());
//获取操作方法名称,依赖于表名称
System.out.println("Manipulation : " + visitor.getTables());
//获取字段名称
System.out.println("fields : " + visitor.getColumns());
System.out.println(visitor.getColumn("define_cdetag","thiSection").getDataType());
System.out.println(visitor.getColumn("define_cdetag","thiSection").getFullName());
System.out.println(visitor.getColumn("define_cdetag","id").isPrimaryKey());
System.out.println(visitor.getTableStat("define_cdetag"));
}
}
}
程序的输入如下,可以看到可以解析到字段信息,主键信息
CREATE TABLE `define_cdetag` (
`id` int(32) UNSIGNED NOT NULL COMMENT '配置项使用时标识',
`thiSection` varchar(32) DEFAULT NULL COMMENT 'StageID白名单区间',
`thiExceptList` text COMMENT 'test名单列表',
PRIMARY KEY (`id`)
) ENGINE = InnoDB CHARSET = utf8 COMMENT 'test';
size is:1
一月 17, 2019 11:33:45 下午 com.alibaba.druid.sql.repository.SchemaRepository info
信息: replaced table 'define_cdetag'
Manipulation : {define_cdetag=Create}
fields : [define_cdetag.id, define_cdetag.thiSection, define_cdetag.thiExceptList]
varchar
`define_cdetag`.`thiSection`
true
Create
其实还有更多的DML相关的辅助信息,整个一套体系是比较全的。