一、简介
1、概念
Druid是Java语言中最好的数据库连接池。Druid能够提供强大的监控和扩展功能。
https://github.com/alibaba/druid/wiki/%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98
2、各种数据库连接池对比
主要功能对比
Druid | BoneCP | DBCP | C3P0 | Proxool | JBoss | Tomcat-Jdbc | |
LRU | 是 | 否 | 是 | 否 | 是 | 是 | ? |
PSCache | 是 | 是 | 是 | 是 | 否 | 否 | 是 |
PSCache-Oracle-Optimized | 是 | 否 | 否 | 否 | 否 | 否 | 否 |
ExceptionSorter | 是 | 否 | 否 | 否 | 否 | 是 | 否 |
更新维护 | 是 | 否 | 否 | 否 | 否 | ? | 是 |
LRU
是一个性能关键指标,特别Oracle,每个Connection对应数据库端的一个进程,如果数据库连接池遵从LRU,有助于数据库服务器优化,这是重要的指标。在测试中,Druid、DBCP、Proxool是遵守LRU的。BoneCP、C3P0则不是。BoneCP在mock环境下性能可能好,但在真实环境中则就不好了。
PSCache
PSCache是数据库连接池的关键指标。在Oracle中,类似SELECT NAME FROM USER WHERE ID = ?这样的SQL,启用PSCache和不启用PSCache的性能可能是相差一个数量级的。Proxool是不支持PSCache的数据库连接池,如果你使用Oracle、SQL Server、DB2、Sybase这样支持游标的数据库,那你就完全不用考虑Proxool。
PSCache-Oracle-Optimized
Oracle 10系列的Driver,如果开启PSCache,会占用大量的内存,必须做特别的处理,启用内部的EnterImplicitCache等方法优化才能够减少内存的占用。这个功能只有DruidDataSource有。如果你使用的是Oracle Jdbc,你应该毫不犹豫采用DruidDataSource。
ExceptionSorter
ExceptionSorter是一个很重要的容错特性,如果一个连接产生了一个不可恢复的错误,必须立刻从连接池中去掉,否则会连续产生大量错误。这个特性,目前只有JBossDataSource和Druid实现。Druid的实现参考自JBossDataSource,经过长期生产反馈补充。
二、相应API
1、参考地址:
https://github.com/alibaba/druid/issues/2457 https://github.com/alibaba/druid/issues/2426
2、格式化SQL
String sql = "CREATE TABLE `my_user` (\n" + " `id` int(11) DEFAULT NULL COMMENT 'ID',\n" + " `name` varchar(255) DEFAULT NULL COMMENT '名称',\n" + " `sex` int(11) DEFAULT NULL COMMENT '性别(1:男。2:女)',\n" + " `address` varchar(64) DEFAULT NULL COMMENT '地址',\n" + " `create_time` datetime DEFAULT NULL COMMENT '创建时间',\n" + " `update_time` datetime DEFAULT NULL COMMENT '更新时间'\n" + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户表'"; // 格式化SQL(假如SQL为多个SQL拼接,则list数量会大于0) List<SQLStatement> sqlStatements = SQLUtils.parseStatements(sql, JdbcConstants.MYSQL); SQLStatement sqlStatement = sqlStatements.get(0);
3、解析SQL,获取表名
SQLCreateTableStatement sqlCreateTableStatement = (SQLCreateTableStatement) SQLUtils.parseStatements(sql, JdbcConstants.MYSQL).get(0); String tableName = sqlCreateTableStatement.getTableName(); SQLName name = sqlCreateTableStatement.getName();
4、解析SQL,获取列名称
SQLCreateTableStatement sqlCreateTableStatement = (SQLCreateTableStatement) SQLUtils.parseStatements(sql, JdbcConstants.MYSQL).get(0); List<SQLColumnDefinition> columnDefinitions = sqlCreateTableStatement.getColumnDefinitions(); for (SQLColumnDefinition column : columnDefinitions) { String name = column.getName().toString(); String comment = column.getComment().toString(); }
5、替换表名
List<SQLStatement> stmtList = SQLUtils.parseStatements(sql, JdbcConstants.MYSQL); HashMap<String, String> hashMap = new HashMap<>(); hashMap.put("old_table", "new_table"); String changeSQL = SQLUtils.toSQLString(stmtList, JdbcConstants.MYSQL, null, new SQLUtils.FormatOption(true, false), hashMap);
三、支持数据源类型
case oracle: case oceanbase_oracle: case mysql: case mariadb: case drds: case elastic_search: case postgresql: case edb: case sqlserver: case jtds: case h2: case blink: case db2: case odps: case phoenix: case hive: case presto: case trino: case ads: case antspark: case clickhouse: