目录
一、项目介绍
1、Druid简介
Druid连接池是阿里巴巴开源的数据库连接池项目。Druid连接池为监控而生,内置强大的监控功能,监控特性不影响性能。功能强大,能防SQL注入,内置Loging能诊断Hack应用行为。
Github项目地址 https://github.com/alibaba/druid
文档 https://github.com/alibaba/druid/wiki
监控 http://x.x.x.x/druid/index.html
2、模块划分
源码里模块描述:
filter:增加自定义的扩展能力
mock:测试模块,可以使用mock模块做一些模拟测试
pool:核心,入口是DruidDataSource;
proxy:代理层
sql:负责sql解析的工作
stat:扩展能力实现,例如基于filter的监控,真正的实现在stat文件夹
support:一些附加功能,比如Json解析等
util:工具类
wall:防火墙相关,防止sql注入等操作,但是实际上对于现在的项目,对于sql注入都在网关层做了处理,不会真正到数据库连接池层面在做处理。
二、快速概览DruidDataSource数据结构
pool是Druid中最核心的目录,而DruidDataSource是pool中最关键的类之一,其承载了连接池的启动、关闭、以及连接的获取和管理等功能。
DruidDataSource继承了DruidAbstractDataSource,两个类内部有大量的变量,用来设置连接池的各种参数。
三、DruidDataSource入口概览
连接池在使用时最主要就是获取连接,然后使用连接查询操作数据库,那么获取连接基本上就可以作为连接池的一个入口。
DruidConnectionHolder是连接池中物理连接的载体,在DruidDataSource中,获取连接的getConnection方法,拿到的是DruidPooledConnection。
@Override
public DruidPooledConnection getConnection() throws SQLException {
return getConnection(maxWait);
}
public DruidPooledConnection getConnection(long maxWaitMillis) throws SQLException {
init();
if (filters.size() > 0) {
FilterChainImpl filterChain = new FilterChainImpl(this);
return filterChain.dataSource_connect(this, maxWaitMillis);
} else {
return getConnectionDirect(maxWaitMillis);
}
}
从上述代码可以看到,其首先调用了 init() 方法对连接池做了初始化,然后从连接池中获取连接,获取连接实际调用的是 getConnectionDirect() 方法,在该方法中调用了 getConnectionInternal() 方法获取的连接
四、常见问题
https://github.com/alibaba/druid/wiki/%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98
五、监控及日志
在META-INF/druid-filter.properties文件中配置Filter的别名。
Filter类名 | 别名 |
default | com.alibaba.druid.filter.stat.StatFilter |
stat | com.alibaba.druid.filter.stat.StatFilter |
mergeStat | com.alibaba.druid.filter.stat.MergeStatFilter |
encoding | com.alibaba.druid.filter.encoding.EncodingConvertFilter |
log4j | com.alibaba.druid.filter.logging.Log4jFilter |
log4j2 | com.alibaba.druid.filter.logging.Log4j2Filter |
slf4j | com.alibaba.druid.filter.logging.Slf4jLogFilter |
commonlogging | com.alibaba.druid.filter.logging.CommonsLogFilter |
wall | com.alibaba.druid.wall.WallFilter |
实现的基础组件
- 接口:Filter
- 抽象类:FilterEventAdapter
思考
数据库加密
六、sql 抽象语法树 AST (Abstract Syntax Tree)
https://github.com/alibaba/druid/wiki/Druid_SQL_AST
https://github.com/alibaba/druid/wiki/SQL-Parser
重要接口
SQLASTVisitor
实例讲解
动态修改sql
sqlserver 查询添加 nolock
修改表名称分表
Map<String, String> mapping = Collections.singletonMap("user", "user_01");
String sql2 = "select * from user";
String result2 = SQLUtils.refactor(sql2, JdbcConstants.MYSQL, mapping);
添加分页
String result = PagerUtils.limit(sql, JdbcConstants.SQL_SERVER, 5, 10);
// Assert.assertEquals("SELECT TOP 10 *"
// + "\nFROM test t WITH (nolock)", result);
添加权限,where添加用户ID
SQLUtils.addCondition("select * from t", "userId = 8", null);
添加加密函数sql加密
AES_ENCRYPT(#{driverName}