1 DruidPooledStatement
本來以為pool包收尾了,掃了一下發(fā)現(xiàn)還有statement,這塊比較簡單施流,是對JDBC的Statement進(jìn)行了一些封裝,實(shí)現(xiàn)了與連接池對應(yīng)的功能鄙信,看下類圖:
2 執(zhí)行SQL
DruidPooledStatement 中最重要的就是execute開頭的一系列方法了瞪醋,是執(zhí)行SQL的本體,都是對JDBC的Statement的增強(qiáng)装诡,主要多做了以下:
- checkOpen()校驗(yàn)當(dāng)前statement是否已經(jīng)被關(guān)閉
- incrementExecuteUpdateCount() 對執(zhí)行語句計數(shù)加一,統(tǒng)計用
- transactionRecord()記錄執(zhí)行的sql银受,統(tǒng)計用
- conn.beforeExecute()践盼,從DruidConnectionHolder中獲取連接,并修改其running狀態(tài)為true
- conn.afterExecute(),從DruidConnectionHolder中獲取連接宾巍,并修改其running狀態(tài)為false,并且更新最后活躍時間為當(dāng)前時間戳
3 DruidPooledPreparedStatement
DruidPooledPreparedStatement實(shí)現(xiàn)了JDBC的PreparedStatement咕幻,是執(zhí)行預(yù)編譯的SQL用,跟Connection相同顶霞,引入了PreparedStatementHolder這樣一個Holder類肄程,同樣定義了一些統(tǒng)計屬性,其中有個屬性pooling选浑,是否池化蓝厌,引出了PreparedStatementPool,里面用LinkedHashMap實(shí)現(xiàn)了LRU古徒,一個cache類用來緩存預(yù)編譯過的statement拓提;
cache的key定義了一個類,PreparedStatementKey隧膘,重寫了hashcode和equals方法代态,很有意思地參考了String的hashcode,用了31這個質(zhì)數(shù)作進(jìn)制來計算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是用來執(zhí)行函數(shù)或者存儲過程的互墓,在當(dāng)下的大環(huán)境下,用得真的很少就略過了吧蒋搜。
5 總結(jié)
druid在JDBC的statement基礎(chǔ)上篡撵,封裝了一些類來擴(kuò)展自己的屬性和功能,一般在工程環(huán)境下豆挽,基本就用AOP或者裝飾器模式來實(shí)現(xiàn)(感覺這個Holder有點(diǎn)像裝飾器育谬,又有點(diǎn)像單例的Holder)的,寫框架的時候帮哈,這種方式還是很值得借鑒的膛檀,很內(nèi)聚、高效娘侍,也沒有額外的引用
cache的使用很巧妙咖刃,但是在刷文章的時候看到過一個問題,雖然在后續(xù)版本中修復(fù)了憾筏,但還是分享一下:
探究Druid連接池“違反協(xié)議”異常
這個問題拋的是SQL異常嚎杨,問題卻出在緩存上,對與緩的狀態(tài)和刷新策略氧腰,有了新的認(rèn)識