SE高階(15):JBDC—③數據庫連接池的介紹、使用和配置


    首先要知道數據庫連接(Connection對象)的創建和關閉是非常浪費系統資源的,如果是使用常規的數據庫連接方式來操作數據庫,當用戶變多時,每次訪問數據庫都要創建大量的Connnection對象,使用完成後關閉連接。這一過程頻繁地使用時,會導致程序性能急劇下降。如果項目存在頻繁訪問數據庫的操作,則應該使用數據庫連接池來管理數據庫連接,可以顯著提升程序運行效率。


數據庫連接池原理

先回顧一下Java程序訪問數據庫的步驟:
①加載載數據庫驅動程序-->②通過jdbc建立數據庫連接-->③訪問數據庫,執行sql語句-->④關閉數據庫連接。
        如果是一個網站,每次用戶進行查詢或者登錄等訪問數據庫的操作,則數據庫連接就會不停地創建,然後又關閉,系統資源被毫無節制的分配,如果連接過多,甚至會導致服務器的崩潰。所以在每次使用完數據庫連接後,不對其進行關閉,而是存儲起來,等待下一次的使用,這樣就能避免重複創建數據庫連接和關閉連接所帶來的時間消耗,從而做到對數據庫連接的有效管理,這就是數據庫連接池的原理。關於連接池,Java中的許多連接池也是類似原理,例如線程池、對象池等,其優勢就是減少資源頻繁分配所帶來的延遲,從而提高性能。

數據庫連接池的介紹

在Java中有一個DataSource接口類,所有的連接池都是對該接口的實現。數據源在網上有許多種,但大體差不多,所以下面就簡單介紹一下DBCP數據源和C3P0數據源的使用方式,但也可以自己去實現該接口,完成一個功能簡單的連接池。除了上面說的兩個數據源,另外推薦使用阿里的Druid數據源,功能比較強大。
DBCP數據源和C3P0數據源以及配置文件都已經打包好了,需要的自行下載:數據庫連接池jar包下載

DBCP數據源

相關配置參數
常用的例如驅動程序、數據庫地址(url)和賬戶密碼的作用就不說了,DBCP的主要參數如下:
initialSize

初始化連接:連接池啓動時創建的連接數量;
maxActive

最大活動連接:連接池在同一時間能夠分配的最大活動連接的數量, 設爲負數表示不限制;
maxIdle

最大空閒連接:連接池中容許保持空閒狀態的最大連接數量,超過的空閒連接將被釋放,設爲負數表示不限制;
minIdle

最小空閒連接:連接池中容許保持空閒狀態的最小連接數量,低於這個數量將創建新的連接,設爲0則不創建;
maxWait
 
最大等待時間:當沒有可用連接時,連接池等待連接被歸還的最大時間(以毫秒計數),超過時間則拋出異常,設爲-1表示無限等待。
使用DBCP需要導入兩個包commons-dbcp-1.4.jar和commons-pool-1.6.jar,這兩個包可在官網Apache commons下載,至於版本根據個人來選擇。配置DBCP數據源可以採用多種方式配置,非Web項目的話就用*.properties文件或者代碼配置,在Web項目中當然最好使用JNDL(Java命名和目錄接口服務)。
這裏採用屬性文件的方式來配置DBCP數據源,配置列表如下:
#數據庫驅動包程序
driverClassName=com.mysql.jdbc.Driver
#訪問的數據庫地址 ,高版本Mysql要求使用SSL,這裏改成false,就沒警告了。
url=jdbc:mysql://localhost:3306/testdb?useSSL=false
#數據庫用戶
username=root
#數據庫密碼
password=1234
#初始連接數
initialSize=5
#最大活動連接數
maxActive=10
#最小空閒數
minIdle=3
#超過時長 6s
maxWait=60000
public class DBCPUtils{
	private static DataSource ds = null;//數據源只需要一個,設爲static。
	//靜態塊只加載一次
	static {
		try {
			InputStream is = new FileInputStream("dbconfig.properties");//加載配置文件
			Properties prop = new Properties();
			prop.load(is);
			//使用DBCP的數據源工廠來創建數據源
			ds = BasicDataSourceFactory.createDataSource(prop);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	/**
	 * 使用DBCP數據源來獲取數據庫連接
	 */
	public static Connection getConnection() {
		Connection conn = null; 
		try {
			conn = ds.getConnection();//從連接池中拿出一個連接
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return conn;
	}
	/**
	 * 關閉資源
	 */
	public void close(Connection conn, Statement st, ResultSet rs) {
		//關閉結果集對象
		if(rs != null){
			try {
				rs.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		//關閉執行SQL語句的Statement對象
		if(st != null) {
			try {
				st.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		//關閉連接,並非真正關閉,而是返回連接池
		if(conn != null) {
			try {
				conn.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}
}
代碼裏面配置DBCP數據源(不推薦,僅作了解)
	private static BasicDataSource ds = null;
	static {
		//創建數據源對象
		ds = new BasicDataSource();
		ds.setDriverClassName("com.mysql.jdbc.Driver");
		ds.setUrl("jdbc:mysql://localhost:3306/testdb?useSSL=false");
		ds.setUsername("root");
		ds.setPassword("1234");
		ds.setInitialSize(5);
		ds.setMaxActive(25);
		ds.setMinIdle(10);
	}

C3P0數據源

和DBCP數據源一樣,需要導入兩個包:c3p0-0.9.5.2.jar 和 mchange-commons-java-0.2.11.jar。
相關配置參數
initialPoolSize:連接池初始化時創建的連接數,default : 3,取值應在minPoolSize與maxPoolSize之間。
minPoolSize
:連接池保持的最小連接數,default :3
maxPoolSize
:連接池中擁有的最大連接數,如果獲得新連接時連接總數超過該值則不再獲取新連接,而是等待其他連接釋放,default :15。
acquireIncrement
:連接池在無空閒連接可用時一次性創建的新數據庫連接數,default :3
maxIdleTime
:連接的最大空閒時間,如果超過這個時間,某個連接還未被使用,則會斷開這個連接。如果爲0,則永遠不會斷開連接,default : 0 。
idleConnectionTestPeriod
:每900秒檢查所有連接池中的空閒連接
acquireRetryAttempts:連接池在獲得新連接失敗時重試的次數,如果小於等於0則無限重試直至連接獲得成功。

配置方式推薦兩種:一是類似上面配置DBCP數據源所採用的屬性文件方式,但C3P0的配置屬性文件名必須爲c3p0.properties,而且屬性名爲c3p0.屬性名,不然沒法解析。最重要的存放路徑一定要對,不然會找不到,從而一直出現異常;二是採用XML配置文件,在類路徑下新建一個c3p0-config.xml文件。

如圖所示,要放在存放類文件的路徑之下,不然找不到。


使用properties方式

#mysql驅動程序
c3p0.driverClass=com.mysql.jdbc.Driver
#數據庫地址。高版本Mysql要求使用SSL,這裏改成false,就沒警告了。
c3p0.jdbcUrl=jdbc:mysql://localhost:3306/testdb?useSSL=false
#用戶
c3p0.user=root
#密碼
c3p0.password=1234
#初始連接數
c3p0.InitialPoolSize = 5
#最大連接數
c3p0.maxPoolSize=20
#最小連接數  
c3p0.minPoolSize=5
#連接的最大空閒時間,單位s
c3p0.maxIdleTime=10  
#獲得新連接失敗時重試的次數  
c3p0.acquireRetryAttempts=30  
#連接池獲得新連接時的間隔時間  
c3p0.acquireRetryDelay=1000 


使用XML配置方式

<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
	<!-- 默認配置,創建c3p0連接池對象時,沒有指定名字,則使用該配置 -->
	<default-config>
		<property name="driverClass">com.mysql.jdbc.Driver</property>
		<property name="jdbcUrl">jdbc:mysql://localhost:3306/testdb?useSSL=false</property>
		<property name="user">root</property>
		<property name="password">1234</property>		
		<!-- 省略設置參數,採用默認設定-->
	</default-config>
	
	<!-- 命名配置,創建c3p0連接池對象時,指定該名字,則使用該配置 -->
	<named-config name="MYSQL">
		<property name="driverClass">com.mysql.jdbc.Driver</property>
		<property name="jdbcUrl">jdbc:mysql://localhost:3306/testdb?useSSL=false</property>
		<property name="user">root</property>
		<property name="password">1234</property>		
		<!-- 設置配置參數 -->
		<property name="initialPoolSize">5</property>
		<property name="maxPoolSize">25</property>
		<property name="minPoolSize">5</property>
		<property name="maxIdleTime">60</property>				<!-- 連接的最大空閒時間,單位s -->
		<property name="acquireRetryAttempts">30</property>		<!-- 獲取連接失敗時,重試次數 -->
		<property name="acquireRetryDelay">30</property>		<!-- 連接池獲得新連接時的間隔時間   -->
	</named-config>
</c3p0-config>

c3p0獲取數據庫連接的代碼

public class C3p0Util {
	private static ComboPooledDataSource ds =null; 
	static {
		//指定名字,就使用該命名的配置;未指定則使用默認配置。
		ds = new ComboPooledDataSource("MYSQL");
	}
	/**
	 * 從連接池獲取數據庫連接
	 */
	public static Connection getConnection() throws SQLException {
		return ds.getConnection();
	}
	//省略關閉資源方法,和上面DBCP數據源的一樣
}

以上就是最常用的兩大開源數據庫連接池的使用方法和配置方式,但這兩個數據庫連接池都沒有連接監控,算是一個缺點,但數據庫連接池proxool支持連接池監控,感興趣可以自行了解。



發佈了61 篇原創文章 · 獲贊 24 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章