數據庫鏈接池的基本思想:就是爲數據庫鏈接創建一個「緩衝池」。預先在緩衝池中放入必定數量的鏈接,當須要創建數據庫鏈接時,只需從「緩衝池」中取出一個,使用完畢以後再放回去。java
數據庫鏈接池在初始化時將建立必定數量的數據庫鏈接放到鏈接池中,這些數據庫鏈接的數量是由最小數據庫鏈接數來設定的。不管這些數據庫鏈接是否被使用,鏈接池都將一直保證至少擁有這麼多的鏈接數量。鏈接池的最大數據庫鏈接數量限定了這個鏈接池能佔有的最大鏈接數,當應用程序向鏈接池請求的鏈接數超過最大鏈接數量時,這些請求將被加入到等待隊列中。mysql
數據庫鏈接池技術的優勢git
1. 資源重用github
因爲數據庫鏈接得以重用,避免了頻繁建立,釋放鏈接引發的大量性能開銷。在減小系統消耗的基礎上,另外一方面也增長了系統運行環境的平穩性。web
2. 更快的系統反應速度sql
數據庫鏈接池在初始化過程當中,每每已經建立了若干數據庫鏈接置於鏈接池中備用。此時鏈接的初始化工做均已完成。對於業務請求處理而言,直接利用現有可用鏈接,避免了數據庫鏈接初始化和釋放過程的時間開銷,從而減小了系統的響應時間數據庫
3. 新的資源分配手段緩存
對於多應用共享同一數據庫的系統而言,可在應用層經過數據庫鏈接池的配置,實現某一應用最大可用數據庫鏈接數的限制,避免某一應用獨佔全部的數據庫資源tomcat
4. 統一的鏈接管理,避免數據庫鏈接泄漏安全
在較爲完善的數據庫鏈接池實現中,可根據預先的佔用超時設定,強制回收被佔用鏈接,從而避免了常規數據庫鏈接操做中可能出現的資源泄露
//使用C3P0數據庫鏈接池的方式,獲取數據庫的鏈接:不推薦 public static Connection getConnection1() throws Exception{ ComboPooledDataSource cpds = new ComboPooledDataSource(); cpds.setDriverClass("com.mysql.jdbc.Driver"); cpds.setJdbcUrl("jdbc:mysql://localhost:3306/test"); cpds.setUser("root"); cpds.setPassword("abc123"); // cpds.setMaxPoolSize(100); Connection conn = cpds.getConnection(); return conn; }
//使用C3P0數據庫鏈接池的配置文件方式,獲取數據庫的鏈接:推薦 private static DataSource cpds = new ComboPooledDataSource("helloc3p0"); public static Connection getConnection2() throws SQLException{ Connection conn = cpds.getConnection(); return conn; }
其中,src下的配置文件爲:【c3p0-config.xml】
<?xml version="1.0" encoding="UTF-8"?> <c3p0-config> <named-config name="helloc3p0"> <!-- 獲取鏈接的4個基本信息 --> <property name="user">root</property> <property name="password">abc123</property> <property name="jdbcUrl">jdbc:mysql:///test</property> <property name="driverClass">com.mysql.jdbc.Driver</property> <!-- 涉及到數據庫鏈接池的管理的相關屬性的設置 --> <!-- 若數據庫中鏈接數不足時, 一次向數據庫服務器申請多少個鏈接 --> <property name="acquireIncrement">5</property> <!-- 初始化數據庫鏈接池時鏈接的數量 --> <property name="initialPoolSize">5</property> <!-- 數據庫鏈接池中的最小的數據庫鏈接數 --> <property name="minPoolSize">5</property> <!-- 數據庫鏈接池中的最大的數據庫鏈接數 --> <property name="maxPoolSize">10</property> <!-- C3P0 數據庫鏈接池能夠維護的 Statement 的個數 --> <property name="maxStatements">20</property> <!-- 每一個鏈接同時可使用的 Statement 對象的個數 --> <property name="maxStatementsPerConnection">5</property> </named-config> </c3p0-config>
屬性 | 默認值 | 說明 |
---|---|---|
initialSize | 0 | 鏈接池啓動時建立的初始化鏈接數量 |
maxActive | 8 | 鏈接池中可同時鏈接的最大的鏈接數 |
maxIdle | 8 | 鏈接池中最大的空閒的鏈接數,超過的空閒鏈接將被釋放,若是設置爲負數表示不限制 |
minIdle | 0 | 鏈接池中最小的空閒的鏈接數,低於這個數量會被建立新的鏈接。該參數越接近maxIdle,性能越好,由於鏈接的建立和銷燬,都是須要消耗資源的;可是不能太大。 |
maxWait | 無限制 | 最大等待時間,當沒有可用鏈接時,鏈接池等待鏈接釋放的最大時間,超過該時間限制會拋出異常,若是設置-1表示無限等待 |
poolPreparedStatements | false | 開啓池的Statement是否prepared |
maxOpenPreparedStatements | 無限制 | 開啓池的prepared 後的同時最大鏈接數 |
minEvictableIdleTimeMillis | 鏈接池中鏈接,在時間段內一直空閒, 被逐出鏈接池的時間 | |
removeAbandonedTimeout | 300 | 超過期間限制,回收沒有用(廢棄)的鏈接 |
removeAbandoned | false | 超過removeAbandonedTimeout時間後,是否進 行沒用鏈接(廢棄)的回收 |
public static Connection getConnection3() throws Exception { BasicDataSource source = new BasicDataSource(); source.setDriverClassName("com.mysql.jdbc.Driver"); source.setUrl("jdbc:mysql:///test"); source.setUsername("root"); source.setPassword("abc123"); // source.setInitialSize(10); Connection conn = source.getConnection(); return conn; }
//使用dbcp數據庫鏈接池的配置文件方式,獲取數據庫的鏈接:推薦 private static DataSource source = null; static{ try { Properties pros = new Properties(); InputStream is = DBCPTest.class.getClassLoader().getResourceAsStream("dbcp.properties"); pros.load(is); //根據提供的BasicDataSourceFactory建立對應的DataSource對象 source = BasicDataSourceFactory.createDataSource(pros); } catch (Exception e) { e.printStackTrace(); } } public static Connection getConnection4() throws Exception { Connection conn = source.getConnection(); return conn; }
其中,src下的配置文件爲:【dbcp.properties】
driverClassName=com.mysql.jdbc.Driver url=jdbc:mysql://localhost:3306/test?rewriteBatchedStatements=true&useServerPrepStmts=false username=root password=abc123 initialSize=10 #...
Druid是阿里巴巴開源平臺上一個數據庫鏈接池實現,它結合了C3P0、DBCP、Proxool等DB池的優勢,同時加入了日誌監控,能夠很好的監控DB池鏈接和SQL的執行狀況,能夠說是針對監控而生的DB鏈接池,能夠說是目前最好的鏈接池之一。
package com.atguigu.druid; import java.sql.Connection; import java.util.Properties; import javax.sql.DataSource; import com.alibaba.druid.pool.DruidDataSourceFactory; public class TestDruid { public static void main(String[] args) throws Exception { Properties pro = new Properties(); pro.load(TestDruid.class.getClassLoader().getResourceAsStream("druid.properties")); DataSource ds = DruidDataSourceFactory.createDataSource(pro); Connection conn = ds.getConnection(); System.out.println(conn); } }
其中,src下的配置文件爲:【druid.properties】
url=jdbc:mysql://localhost:3306/test?rewriteBatchedStatements=true username=root password=123456 driverClassName=com.mysql.jdbc.Driver initialSize=10 maxActive=20 maxWait=1000 filters=wall
配置 | 缺省 | 說明 |
---|---|---|
name | 配置這個屬性的意義在於,若是存在多個數據源,監控的時候能夠經過名字來區分開來。 若是沒有配置,將會生成一個名字,格式是:」DataSource-」 + System.identityHashCode(this) | |
url | 鏈接數據庫的url,不一樣數據庫不同。例如:mysql : jdbc:mysql://10.20.153.104:3306/druid2 oracle : jdbc:oracle:thin:@10.20.149.85:1521:ocnauto | |
username | 鏈接數據庫的用戶名 | |
password | 鏈接數據庫的密碼。若是你不但願密碼直接寫在配置文件中,可使用ConfigFilter。詳細看這裏:https://github.com/alibaba/druid/wiki/%E4%BD%BF%E7%94%A8ConfigFilter | |
driverClassName | 根據url自動識別 這一項可配可不配,若是不配置druid會根據url自動識別dbType,而後選擇相應的driverClassName(建議配置下) | |
initialSize | 0 | 初始化時創建物理鏈接的個數。初始化發生在顯示調用init方法,或者第一次getConnection時 |
maxActive | 8 | 最大鏈接池數量 |
maxIdle | 8 | 已經再也不使用,配置了也沒效果 |
minIdle | 最小鏈接池數量 | |
maxWait | 獲取鏈接時最大等待時間,單位毫秒。配置了maxWait以後,缺省啓用公平鎖,併發效率會有所降低,若是須要能夠經過配置useUnfairLock屬性爲true使用非公平鎖。 | |
poolPreparedStatements | false | 是否緩存preparedStatement,也就是PSCache。PSCache對支持遊標的數據庫性能提高巨大,好比說oracle。在mysql下建議關閉。 |
maxOpenPreparedStatements | -1 | 要啓用PSCache,必須配置大於0,當大於0時,poolPreparedStatements自動觸發修改成true。在Druid中,不會存在Oracle下PSCache佔用內存過多的問題,能夠把這個數值配置大一些,好比說100 |
validationQuery | 用來檢測鏈接是否有效的sql,要求是一個查詢語句。若是validationQuery爲null,testOnBorrow、testOnReturn、testWhileIdle都不會其做用。 | |
testOnBorrow | true | 申請鏈接時執行validationQuery檢測鏈接是否有效,作了這個配置會下降性能。 |
testOnReturn | false | 歸還鏈接時執行validationQuery檢測鏈接是否有效,作了這個配置會下降性能 |
testWhileIdle | false | 建議配置爲true,不影響性能,而且保證安全性。申請鏈接的時候檢測,若是空閒時間大於timeBetweenEvictionRunsMillis,執行validationQuery檢測鏈接是否有效。 |
timeBetweenEvictionRunsMillis | 有兩個含義: 1)Destroy線程會檢測鏈接的間隔時間2)testWhileIdle的判斷依據,詳細看testWhileIdle屬性的說明 | |
numTestsPerEvictionRun | 再也不使用,一個DruidDataSource只支持一個EvictionRun | |
minEvictableIdleTimeMillis | ||
connectionInitSqls | 物理鏈接初始化的時候執行的sql | |
exceptionSorter | 根據dbType自動識別 當數據庫拋出一些不可恢復的異常時,拋棄鏈接 | |
filters | 屬性類型是字符串,經過別名的方式配置擴展插件,經常使用的插件有: 監控統計用的filter:stat日誌用的filter:log4j防護sql注入的filter:wall | |
proxyFilters | 類型是List,若是同時配置了filters和proxyFilters,是組合關係,並不是替換關係 |