Java 數(shù)據(jù)庫(kù)連接池筆記

JDBC

Java 數(shù)據(jù)庫(kù)連接(Java Database Connectivity,簡(jiǎn)稱JDBC)是 Java 語(yǔ)言中用來(lái)規(guī)范客戶端程序如何來(lái)訪問(wèn)數(shù)據(jù)庫(kù)的應(yīng)用程序接口右冻,提供了諸如查詢和更新數(shù)據(jù)庫(kù)中數(shù)據(jù)的方法冕香。

JDBC 的創(chuàng)建

使用 JDBC 訪問(wèn)數(shù)據(jù)庫(kù)的流程:

  1. 加載 JDBC 驅(qū)動(dòng)
  2. 連接數(shù)據(jù)庫(kù)
  3. 執(zhí)行 SQL 查詢
  4. 從結(jié)果集中提取數(shù)據(jù)
  5. 處理結(jié)果集
  6. 清理環(huán)境改衩,關(guān)閉所有的數(shù)據(jù)庫(kù)資源橙弱,釋放內(nèi)存

關(guān)于 JDBC 更詳細(xì)的介紹與使用:Java-MySQL連接

JDBC 的缺點(diǎn)

熟悉 JDBC 編程的具伍,我們知道它存在很多缺點(diǎn)藕筋,如:

  1. 數(shù)據(jù)庫(kù)連接纵散,使用時(shí)創(chuàng)建,不使用立即釋放隐圾,對(duì)數(shù)據(jù)庫(kù)進(jìn)行頻繁連接開(kāi)啟和關(guān)閉伍掀,造成數(shù)據(jù)庫(kù)資源浪費(fèi),影響了數(shù)據(jù)庫(kù)的性能暇藏。
  2. 將 sql 語(yǔ)句硬編碼到j(luò)ava代碼中蜜笤,如果 sql 語(yǔ)句的修改,需要重新編譯java代碼盐碱,不利于系統(tǒng)的維護(hù)
  3. 向 preparedStatement 中設(shè)置參數(shù)把兔,對(duì)占位符位置和參數(shù)值,硬編碼在代碼中瓮顽,不利于系統(tǒng)的維護(hù)垛贤。
  4. 從 resultSet 中遍歷結(jié)果集數(shù)據(jù)時(shí),存在硬編碼趣倾,將獲取表的字段進(jìn)行硬編碼聘惦,不利于系統(tǒng)的維護(hù)。

針對(duì)上述缺點(diǎn)儒恋,我們對(duì)應(yīng)的解決方案:

  • 問(wèn)題1:使用數(shù)據(jù)庫(kù)的連接池管理數(shù)據(jù)庫(kù)的連接善绎。
  • 問(wèn)題2:將 sql 語(yǔ)句配置到 xml 配置文件中,即使 sql 變化诫尽,不需要對(duì) java 進(jìn)行重新編譯
  • 問(wèn)題3:將 sql 語(yǔ)句和參數(shù)值配置到 xml 中
  • 問(wèn)題4:將查詢的結(jié)果自動(dòng)的映射的 java 的對(duì)象

總的來(lái)說(shuō)禀酱,我們主要會(huì)采用數(shù)據(jù)庫(kù)連接池解決數(shù)據(jù)庫(kù)頻繁鏈接與釋放問(wèn)題,采用配置文件解決 sql 語(yǔ)句硬編碼問(wèn)題牧嫉。

數(shù)據(jù)庫(kù)連接池

連接池技術(shù)的核心思想是:連接復(fù)用剂跟,通過(guò)建立一個(gè)數(shù)據(jù)庫(kù)連接池以及一套連接使用、分配酣藻、管理策略曹洽,使得該連接池中的連接可以得到高效、安全的復(fù)用辽剧,避免了數(shù)據(jù)庫(kù)連接頻繁建立送淆、關(guān)閉的開(kāi)銷。另外怕轿,由于對(duì) JDBC 中的原始連接進(jìn)行了封裝偷崩,從而方便了數(shù)據(jù)庫(kù)應(yīng)用對(duì)于連接的使用(特別是對(duì)于事務(wù)處理)辟拷,提高了開(kāi)發(fā)效率,也正是因?yàn)檫@個(gè)封裝層的存在阐斜,隔離了應(yīng)用的本身的處理邏輯和具體數(shù)據(jù)庫(kù)訪問(wèn)邏輯衫冻,使應(yīng)用本身的復(fù)用成為可能。

連接池的操作:

  1. 建立數(shù)據(jù)庫(kù)連接池對(duì)象(服務(wù)器啟動(dòng))谒出。
  2. 按照事先指定的參數(shù)創(chuàng)建初始數(shù)量的數(shù)據(jù)庫(kù)連接(即:空閑連接數(shù))羽杰。
  3. 對(duì)于一個(gè)數(shù)據(jù)庫(kù)訪問(wèn)請(qǐng)求,直接從連接池中得到一個(gè)連接到推。如果數(shù)據(jù)庫(kù)連接池對(duì)象中沒(méi)有空閑的連接考赛,且連接數(shù)沒(méi)有達(dá)到最大(即:最大活躍連接數(shù)),創(chuàng)建一個(gè)新的數(shù)據(jù)庫(kù)連接莉测。
  4. 存取數(shù)據(jù)庫(kù)颜骤。
  5. 關(guān)閉數(shù)據(jù)庫(kù),釋放所有數(shù)據(jù)庫(kù)連接(此時(shí)的關(guān)閉數(shù)據(jù)庫(kù)連接捣卤,并非真正關(guān)閉忍抽,而是將其放入空閑隊(duì)列中。如實(shí)際空閑連接數(shù)大于初始空閑連接數(shù)則釋放連接)董朝。
  6. 釋放數(shù)據(jù)庫(kù)連接池對(duì)象(服務(wù)器停止鸠项、維護(hù)期間,釋放數(shù)據(jù)庫(kù)連接池對(duì)象子姜,并釋放所有連接)祟绊。

自定義數(shù)據(jù)庫(kù)連接池

大致了解了數(shù)據(jù)庫(kù)連接池的原理與創(chuàng)建方法,我們可以自己編寫一個(gè)數(shù)據(jù)庫(kù)連接池哥捕,而編寫連接池需實(shí)現(xiàn)javax.sql.DataSource接口牧抽。DataSource接口中定義了兩個(gè)重載的getConnection方法:

  Connection.getConnection() 

  Connection.getConnection(String username, String password) 

自定義一個(gè)類,實(shí)現(xiàn)DataSource接口遥赚,并實(shí)現(xiàn)連接池功能的步驟:

  1. 在自定義類的構(gòu)造函數(shù)中批量創(chuàng)建Connection扬舒,并把創(chuàng)建的連接保存到一個(gè)集合對(duì)象中(LinkedList)。
  2. 在自定義類中實(shí)現(xiàn)Connection.getConnection方法凫佛,讓getConnection方法每次調(diào)用時(shí)讲坎,從集合對(duì)象中取出一個(gè)Connection返回給用戶。
  3. 當(dāng)用戶使用完Connection愧薛,不能調(diào)用Connection.close()方法晨炕,而要使用連接池提供關(guān)閉方法,即將Connection放回到連接池之中(把Connection存入集合對(duì)象中)厚满。

注:Connection對(duì)象應(yīng)保證將自己返回到連接池的集合對(duì)象中府瞄,而不要把Connection還給數(shù)據(jù)庫(kù)碧磅。

實(shí)際編程時(shí)我們并不需要自己編寫連接數(shù)據(jù)庫(kù)代碼碘箍,有一些開(kāi)源組織提供了數(shù)據(jù)庫(kù)連接池的實(shí)現(xiàn)遵馆,我們只要會(huì)使用即可。在我實(shí)習(xí)的公司丰榴,主要使用以下兩種開(kāi)源數(shù)據(jù)庫(kù)連接池:

  • C3P0 數(shù)據(jù)庫(kù)連接池
  • DBCP 數(shù)據(jù)庫(kù)連接池

為此货邓,就這兩種數(shù)據(jù)庫(kù)連接池,我做一簡(jiǎn)單的介紹四濒。

C3P0 數(shù)據(jù)庫(kù)連接池

C3P0 是一個(gè)開(kāi)源的 JDBC 連接池换况,它實(shí)現(xiàn)了數(shù)據(jù)源和 JNDI 綁定,支持 JDBC3 規(guī)范和 JDBC2 的標(biāo)準(zhǔn)擴(kuò)展盗蟆。目前使用它的開(kāi)源項(xiàng)目有Hibernate戈二,Spring 等。

C3P0 所需 JAR 包: c3p0-0.9.2.1.jar 和 mchange-commons-java-0.2.3.4.jar

配置文件常用的屬性:

####### c3p0 #######
c3p0.driverClass=com.mysql.jdbc.Driver
c3p0.jdbcUrl=jdbc:mysql://127.0.0.1:3306/test
c3p0.user=xxxx
c3p0.password=xxxxx

c3p0.initialPoolSize=10 //初始化連接數(shù)
c3p0.minPoolSize=10 //最大連接數(shù)
c3p0.maxPoolSize=30 //最小連接數(shù)
c3p0.maxIdleTime=30 //最大空閑時(shí)間 => 這就是為什么C3P0有自動(dòng)回收的原因
c3p0.acquireIncrement=5 //新增連接數(shù)

當(dāng)創(chuàng)建連接池時(shí)喳资,一次性創(chuàng)建initialPoolSize 個(gè)連接觉吭,當(dāng)連接使用完一次性創(chuàng)建 acquireIncrement 個(gè)連接,連接最大數(shù)量 maxPoolSize 仆邓,當(dāng)連接池連接數(shù)量大于 minPoolSize 鲜滩,經(jīng)過(guò) maxIdleTime 連接沒(méi)有使用, 該連接將被釋放节值。

C3P0 連接創(chuàng)建方式主要分為:配置文件形式和硬編碼形式徙硅,這點(diǎn)和 DBCP 數(shù)據(jù)庫(kù)連接池非常相似,唯一不同的就是配置文件命名規(guī)范不同搞疗,C3P0 配置文件必須命名為 c3p0-config.xml 或 c3p0-config.properties ,并且放在 src 目錄下嗓蘑,而 DBCP 沒(méi)有這樣的要求。

DBCP 數(shù)據(jù)庫(kù)連接池

DBCP(DataBase connection pool), 數(shù)據(jù)庫(kù)連接池匿乃。是 apache 上的一個(gè) java 連接池項(xiàng)目脐往,也是 tomcat 默認(rèn)使用的連接池組件。

DBCP 需要3個(gè)包:common-dbcp.jar,common-pool.jar,common-collections.jar

配置文件常用的屬性:

####### dbcp #######
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/test
username=xxxx
password=xxxxx

initialSize=10
# maxActive=10  // dbcp2中已將MaxActive設(shè)置為MaxTotal
maxTotal=30  // 可以在這個(gè)池中同時(shí)被分配的有效連接數(shù)的最大值扳埂,如設(shè)置為負(fù)數(shù)业簿,則不限制
maxIdle=10  // 可以在池中保持空閑的最大連接數(shù),超出設(shè)置值之外的空閑連接將被回收阳懂,如設(shè)置為負(fù)數(shù)梅尤,則不限制
minIdle=5   // 可以在池中保持空閑的最小連接數(shù),超出設(shè)置值之外的空閑連接將被創(chuàng)建岩调,如設(shè)置為0巷燥,則不創(chuàng)建

關(guān)于 C3P0 和 DBCP 配置文件更詳細(xì)的說(shuō)明,請(qǐng)自行了解号枕。Demo 可參見(jiàn)我的GitHub倉(cāng)庫(kù)缰揪,后續(xù)會(huì)補(bǔ)充測(cè)試代碼。

C3P0 與 DBCP 區(qū)別

  1. C3P0 自動(dòng)回收空閑連接
  • 主要因?yàn)?maxIdleTime 屬性葱淳,當(dāng)連接池連接數(shù)量大于 minPoolSize 钝腺,經(jīng)過(guò) maxIdleTime 連接沒(méi)有使用抛姑, 該連接將被釋放
  1. C3P0 擁有 3 種配置方法,DBCP 擁有 2 種配置方法
  2. 對(duì)數(shù)據(jù)連接的處理方式艳狐,C3P0 提供最大空閑時(shí)間定硝,DBCP 提供最大連接數(shù)
  • 前者當(dāng)連接超過(guò)最大空閑連接時(shí)間時(shí),當(dāng)前連接就會(huì)被斷掉毫目。DBCP 當(dāng)連接數(shù)超過(guò)最大連接數(shù)時(shí)蔬啡,所有連接都會(huì)被斷開(kāi)。

參考鏈接

  1. 數(shù)據(jù)庫(kù)連接池的工作原理
  2. JDBC 進(jìn)階——連接池
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末镀虐,一起剝皮案震驚了整個(gè)濱河市箱蟆,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌刮便,老刑警劉巖顽腾,帶你破解...
    沈念sama閱讀 222,104評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異诺核,居然都是意外死亡抄肖,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,816評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門窖杀,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)漓摩,“玉大人,你說(shuō)我怎么就攤上這事入客」鼙校” “怎么了?”我有些...
    開(kāi)封第一講書人閱讀 168,697評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵桌硫,是天一觀的道長(zhǎng)夭咬。 經(jīng)常有香客問(wèn)我,道長(zhǎng)铆隘,這世上最難降的妖魔是什么卓舵? 我笑而不...
    開(kāi)封第一講書人閱讀 59,836評(píng)論 1 298
  • 正文 為了忘掉前任,我火速辦了婚禮膀钠,結(jié)果婚禮上掏湾,老公的妹妹穿的比我還像新娘。我一直安慰自己肿嘲,他們只是感情好融击,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,851評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著雳窟,像睡著了一般尊浪。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 52,441評(píng)論 1 310
  • 那天拇涤,我揣著相機(jī)與錄音捣作,去河邊找鬼。 笑死工育,一個(gè)胖子當(dāng)著我的面吹牛虾宇,可吹牛的內(nèi)容都是我干的搓彻。 我是一名探鬼主播如绸,決...
    沈念sama閱讀 40,992評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼旭贬!你這毒婦竟也來(lái)了怔接?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 39,899評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤稀轨,失蹤者是張志新(化名)和其女友劉穎扼脐,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體奋刽,經(jīng)...
    沈念sama閱讀 46,457評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡瓦侮,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,529評(píng)論 3 341
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了佣谐。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片肚吏。...
    茶點(diǎn)故事閱讀 40,664評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖狭魂,靈堂內(nèi)的尸體忽然破棺而出罚攀,到底是詐尸還是另有隱情,我是刑警寧澤雌澄,帶...
    沈念sama閱讀 36,346評(píng)論 5 350
  • 正文 年R本政府宣布斋泄,位于F島的核電站,受9級(jí)特大地震影響镐牺,放射性物質(zhì)發(fā)生泄漏炫掐。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,025評(píng)論 3 334
  • 文/蒙蒙 一睬涧、第九天 我趴在偏房一處隱蔽的房頂上張望卒废。 院中可真熱鬧,春花似錦宙地、人聲如沸摔认。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 32,511評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)参袱。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間抹蚀,已是汗流浹背剿牺。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,611評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留环壤,地道東北人晒来。 一個(gè)月前我還...
    沈念sama閱讀 49,081評(píng)論 3 377
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像郑现,于是被迫代替她去往敵國(guó)和親湃崩。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,675評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容

  • 本文包括傳統(tǒng)JDBC的缺點(diǎn)連接池原理自定義連接池開(kāi)源數(shù)據(jù)庫(kù)連接池DBCP連接池C3P0連接池Tomcat內(nèi)置連接池...
    廖少少閱讀 16,754評(píng)論 0 37
  • 前言 數(shù)據(jù)庫(kù)連接池在Java數(shù)據(jù)庫(kù)相關(guān)中間件產(chǎn)品群中接箫,應(yīng)該算是底層最基礎(chǔ)的一類產(chǎn)品攒读,作為企業(yè)應(yīng)用開(kāi)發(fā)必不可少的組件...
    許da廣閱讀 7,183評(píng)論 2 27
  • 最原始的數(shù)據(jù)庫(kù)連接就是我們打開(kāi)一個(gè)連接,使用過(guò)后再關(guān)閉該鏈接來(lái)釋放資源辛友。頻繁的新建打開(kāi)再關(guān)閉連接對(duì)jvm和數(shù)據(jù)庫(kù)都...
    野柳閱讀 6,378評(píng)論 1 11
  • 以一個(gè)xx.png圖片來(lái)說(shuō)內(nèi)部的結(jié)構(gòu)如下: 一開(kāi)始是.png 后面緊跟 寬 高 然后是數(shù)據(jù) 最后是圖片描述(拍攝時(shí)...
    劉書亞的天堂之路閱讀 1,781評(píng)論 2 2
  • 又到一周做自然筆記啦薄扁!這周的主題是……昆蟲(chóng)! 恰巧就看到了小朋友養(yǎng)的蠶寶寶了废累,已處于“眠”時(shí)期的它們開(kāi)始吐絲了哦⊙ ⊙
    db21dd77f543閱讀 362評(píng)論 0 2