用戶每次請求都須要向數據庫得到連接,而數據庫建立鏈接一般須要消耗相對較大的資源,建立時間也較長。假設網站一天10萬訪問量,數據庫服務器就須要建立10萬次鏈接,極大的浪費數據庫的資源,而且極易形成數據庫服務器內存溢出、拓機。以下圖所示:java
數據庫鏈接是一種關鍵的有限的昂貴的資源,這一點在多用戶的網頁應用程序中體現的尤其突出.對數據庫鏈接的管理能顯著影響到整個應用程序的伸縮性和健壯性,影響到程序的性能指標.數據庫鏈接池正式針對這個問題提出來的.數據庫鏈接池負責分配,管理和釋放數據庫鏈接,它容許應用程序重複使用一個現有的數據庫鏈接,而不是從新創建一個。以下圖所示:sql
數據庫鏈接池在初始化時將建立必定數量的數據庫鏈接放到鏈接池中, 這些數據庫鏈接的數量是由最小數據庫鏈接數來設定的.不管這些數據庫鏈接是否被使用,鏈接池都將一直保證至少擁有這麼多的鏈接數量.鏈接池的最大數據庫鏈接數量限定了這個鏈接池能佔有的最大鏈接數,當應用程序向鏈接池請求的鏈接數超過最大鏈接數量時,這些請求將被加入到等待隊列中.數據庫
數據庫鏈接池的最小鏈接數和最大鏈接數的設置要考慮到如下幾個因素:編程
最小鏈接數:是鏈接池一直保持的數據庫鏈接,因此若是應用程序對數據庫鏈接的使用量不大,將會有大量的數據庫鏈接資源被浪費.服務器
最大鏈接數:是鏈接池能申請的最大鏈接數,若是數據庫鏈接請求超過次數,後面的數據庫鏈接請求將被加入到等待隊列中,這會影響之後的數據庫操做oracle
若是最小鏈接數與最大鏈接數相差很大:那麼最早鏈接請求將會獲利,以後超過最小鏈接數量的鏈接請求等價於創建一個新的數據庫鏈接.不過,這些大於最小鏈接數的數據庫鏈接在使用完不會立刻被釋放,他將被放到鏈接池中等待重複使用或是空間超時後被釋放.函數
編寫鏈接池需實現java.sql.DataSource接口。DataSource接口中定義了兩個重載的getConnection方法:性能
Connection getConnection()大數據
Connection getConnection(String username, String password) 優化
實現DataSource接口,並實現鏈接池功能的步驟:
在DataSource構造函數中批量建立與數據庫的鏈接,並把建立的鏈接加入LinkedList對象中。
實現getConnection方法,讓getConnection方法每次調用時,從LinkedList中取一個Connection返回給用戶。
當用戶使用完Connection,調用Connection.close()方法時,Collection對象應保證將本身返回到LinkedList中,而不要把conn還給數據庫。Collection保證將本身返回到LinkedList中是此處編程的難點。
如今不少WEB服務器(Weblogic, WebSphere, Tomcat)都提供了DataSoruce的實現,即鏈接池的實現。一般咱們把DataSource的實現,按其英文含義稱之爲數據源,數據源中都包含了數據庫鏈接池的實現。
也有一些開源組織提供了數據源的獨立實現:
DBCP 數據庫鏈接池
C3P0 數據庫鏈接池
在使用了數據庫鏈接池以後,在項目的實際開發中就不須要編寫鏈接數據庫的代碼了,直接從數據源得到數據庫的鏈接。
DBCP 是 Apache 軟件基金組織下的開源鏈接池實現,要使用DBCP數據源,須要應用程序應在系統中增長以下兩個 jar 文件:
Commons-dbcp.jar:鏈接池的實現
Commons-pool.jar:鏈接池實現的依賴庫
Tomcat 的鏈接池正是採用該鏈接池來實現的。該數據庫鏈接池既能夠與應用服務器整合使用,也可由應用程序獨立使用。
C3P0是一個開源的JDBC鏈接池,它實現了數據源和JNDI綁定,支持JDBC3規範和JDBC2的標準擴展。目前使用它的開源項目有Hibernate,Spring等。C3P0數據源在項目開發中使用得比較多。
導入相關jar包 :
c3p0-0.9.2-pre1.jar、mchange-commons-0.2.jar,若是操做的是Oracle數據庫,那麼還須要導入c3p0-oracle-thin-extras-0.9.2-pre1.jar 。
c3p0與dbcp區別 :
dbcp沒有自動回收空閒鏈接的功能
c3p0有自動回收空閒鏈接功能
在實際開發中,咱們有時候還會使用服務器提供給咱們的數據庫鏈接池,好比咱們但願Tomcat服務器在啓動的時候能夠幫咱們建立一個數據庫鏈接池,那麼咱們在應用程序中就不須要手動去建立數據庫鏈接池,直接使用Tomcat服務器建立好的數據庫鏈接池便可。要想讓Tomcat服務器在啓動的時候幫咱們建立一個數據庫鏈接池,那麼須要簡單配置一下Tomcat服務器。
JNDI(Java Naming and Directory Interface),Java命名和目錄接口,它對應於J2SE中的javax.naming包。
這套API的主要做用在於:它能夠把Java對象放在一個容器中(JNDI容器),併爲容器中的java對象取一個名稱,之後程序想得到Java對象,只需 經過名稱檢索便可。其核心API爲Context,它表明JNDI容器,其lookup方法爲檢索容器中對應名稱的對象。
Tomcat服務器建立的數據源是以JNDI資源的形式發佈的,因此說在Tomat服務器中配置一個數據源實際上就是在配置一個JNDI資源。