美文网首页
Druid连接池源码解析(8)DruidPooledStatem

Druid连接池源码解析(8)DruidPooledStatem

作者: 错乱的三元运算 | 来源:发表于2022-05-19 17:36 被阅读0次

    1 DruidPooledStatement

    本来以为pool包收尾了,扫了一下发现还有statement,这块比较简单,是对JDBC的Statement进行了一些封装,实现了与连接池对应的功能,看下类图:


    DruidPooledStatement.png

    2 执行SQL

    DruidPooledStatement 中最重要的就是execute开头的一系列方法了,是执行SQL的本体,都是对JDBC的Statement的增强,主要多做了以下:

    • checkOpen()校验当前statement是否已经被关闭
    • incrementExecuteUpdateCount() 对执行语句计数加一,统计用
    • transactionRecord()记录执行的sql,统计用
    • conn.beforeExecute(),从DruidConnectionHolder中获取连接,并修改其running状态为true
    • conn.afterExecute(),从DruidConnectionHolder中获取连接,并修改其running状态为false,并且更新最后活跃时间为当前时间戳

    3 DruidPooledPreparedStatement

    DruidPooledPreparedStatement实现了JDBC的PreparedStatement,是执行预编译的SQL用,跟Connection相同,引入了PreparedStatementHolder这样一个Holder类,同样定义了一些统计属性,其中有个属性pooling,是否池化,引出了PreparedStatementPool,里面用LinkedHashMap实现了LRU,一个cache类用来缓存预编译过的statement;
    cache的key定义了一个类,PreparedStatementKey,重写了hashcode和equals方法,很有意思地参考了String的hashcode,用了31这个质数作进制来计算hash,且不仅仅是sql语句相同,需要其他属性都相同才算相同,贴一下源码:

    public int hashCode() {
                final int prime = 31;
                int result = 1;
    
                result = prime * result + ((sql == null) ? 0 : sql.hashCode());
                result = prime * result + ((catalog == null) ? 0 : catalog.hashCode());
                result = prime * result + ((methodType == null) ? 0 : methodType.hashCode());
    
                result = prime * result + resultSetConcurrency;
                result = prime * result + resultSetHoldability;
                result = prime * result + resultSetType;
    
                result = prime * result + autoGeneratedKeys;
    
                result = prime * result + Arrays.hashCode(columnIndexes);
                result = prime * result + Arrays.hashCode(columnNames);
    
                return result;
            }
    

    4 DruidPooledCallableStatement

    CallableStatement是用来执行函数或者存储过程的,在当下的大环境下,用得真的很少就略过了吧。

    5 总结

    druid在JDBC的statement基础上,封装了一些类来扩展自己的属性和功能,一般在工程环境下,基本就用AOP或者装饰器模式来实现(感觉这个Holder有点像装饰器,又有点像单例的Holder)的,写框架的时候,这种方式还是很值得借鉴的,很内聚、高效,也没有额外的引用
    cache的使用很巧妙,但是在刷文章的时候看到过一个问题,虽然在后续版本中修复了,但还是分享一下:
    探究Druid连接池“违反协议”异常
    这个问题抛的是SQL异常,问题却出在缓存上,对与缓的状态和刷新策略,有了新的认识

    相关文章

      网友评论

          本文标题:Druid连接池源码解析(8)DruidPooledStatem

          本文链接:https://www.haomeiwen.com/subject/xgptprtx.html