JDBC--數據庫鏈接池

1、數據庫鏈接池

(1)JDBC數據庫鏈接池的必要性

在使用開發基於數據庫的web程序時,傳統的模式基本是按如下步驟:  java

  • 在主程序(如servlet、beans)中創建數據庫鏈接。
  • 進行sql操做
  • 斷開數據庫鏈接。

這種模式開發,存在的問題:mysql

  • 普通的JDBC數據庫鏈接使用 DriverManager 來獲取,每次向數據庫創建鏈接的時候都要將 Connection 加載到內存中,再驗證用戶名和密碼(得花費0.05s~1s的時間)。須要數據庫鏈接的時候,就向數據庫要求一個,執行完成後再斷開鏈接。這樣的方式將會消耗大量的資源和時間。數據庫的鏈接資源並無獲得很好的重複利用.若同時有幾百人甚至幾千人在線,頻繁的進行數據庫鏈接操做將佔用不少的系統資源,嚴重的甚至會形成服務器的崩潰。
  • 對於每一次數據庫鏈接,使用完後都得斷開。不然,若是程序出現異常而未能關閉,將會致使數據庫系統中的內存泄漏,最終將致使重啓數據庫。
  • 這種開發不能控制被建立的鏈接對象數,系統資源會被毫無顧及的分配出去,如鏈接過多,也可能致使內存泄漏,服務器崩潰。

(2)數據庫鏈接池(connection pool)

  • 基本思想是爲數據庫鏈接創建一個「緩衝池」。預先在緩衝池中放入必定數量的鏈接,當須要創建數據庫鏈接時,只需從「緩衝池」中取出一個,使用完畢以後再放回去。
  • 數據庫鏈接池負責分配、管理和釋放數據庫鏈接,它容許應用程序重複使用一個現有的數據庫鏈接,而不是從新創建一個。
  • 數據庫鏈接池在初始化時將建立必定數量的數據庫鏈接放到鏈接池中,這些數據庫鏈接的數量是由最小數據庫鏈接數來設定的。不管這些數據庫鏈接是否被使用,鏈接池都將一直保證至少擁有這麼多的鏈接數量。鏈接池的最大數據庫鏈接數量限定了這個鏈接池能佔有的最大鏈接數,當應用程序向鏈接池請求的鏈接數超過最大鏈接數量時,這些請求將被加入到等待隊列中。

(3)數據庫鏈接池的工做原理 

(4)數據庫鏈接池技術的優勢

  • 資源重用:因爲數據庫鏈接得以重用,避免了頻繁建立,釋放鏈接引發的大量性能開銷。在減小系統消耗的基礎上,另外一方面也增長了系統運行環境的平穩性。
  • 更快的系統反應速度:數據庫鏈接池在初始化過程當中,每每已經建立了若干數據庫鏈接置於鏈接池中備用。此時鏈接的初始化工做均已完成。對於業務請求處理而言,直接利用現有可用鏈接,避免了數據庫鏈接初始化和釋放過程的時間開銷,從而減小了系統的響應時間
  • 新的資源分配手段:對於多應用共享同一數據庫的系統而言,可在應用層經過數據庫鏈接池的配置,實現某一應用最大可用數據庫鏈接數的限制,避免某一應用獨佔全部的數據庫資源
  • 統一的鏈接管理,避免數據庫鏈接泄露:在較爲完善的數據庫鏈接池實現中,可根據預先的佔用超時設定,強制回收被佔用鏈接,從而避免了常規數據庫鏈接操做中可能出現的資源泄露

(5)開源的數據庫鏈接池

JDBC 的數據庫鏈接池使用 javax.sql.DataSource 來表示,DataSource 只是一個接口,該接口一般由服務器(Weblogic, WebSphere, Tomcat)提供實現,也有一些開源組織提供實現:web

  • DBCP 數據庫鏈接池
  • C3P0 數據庫鏈接池

DataSource 一般被稱爲數據源,它包含鏈接池和鏈接池管理兩個部分,習慣上也常常把 DataSource 稱爲鏈接池.sql

 2、DBCP 數據庫鏈接池

(1)基本用法數據庫

/**
     * 使用 DBCP數據庫鏈接池
     * 1.加入jar包:
     *   commons-dbcp2-2.1.1.jar
     *   commons-pool2-2.4.2.jar
     * 2.建立數據庫鏈接
     * 3.爲數據源實例指定必需的屬性
     * 4.從數據源中獲取數據庫鏈接
     * @throws SQLException
     */
    @Test
    public void test17() throws SQLException {
        BasicDataSource dataSource = null;
        //1.建立DBPC數據源實例
        dataSource = new BasicDataSource();

        //2.爲數據源實例指定必需的屬性
        dataSource.setUsername("root");
        dataSource.setPassword("12345");
        dataSource.setUrl("jdbc:mysql://localhost:3306/jdbctest");
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");

        //3.指定數據庫的一些可選屬性
        //3.1 指定數據庫鏈接池初始化鏈接數的個數
        dataSource.setInitialSize(10);
        //3.2 指定最大鏈接數,同一時間能夠同時向數據庫申請的鏈接數
        dataSource.setMaxTotal(50);
        //3.3 其餘...

        //3.從數據源中獲取數據庫鏈接
        Connection connection = dataSource.getConnection();
        System.out.println(connection.getClass());
    }

(2)更好的使用方法服務器

/**
     * 1. 加載 dbcp的 properties配置文件:配置文件中的鍵須要來自BasicDataSource的屬性
     * 2. 調用 BasicDataSourceFactory的 createDataSource方法才建立數據庫鏈接
     * 3. 從 DataSource實例中獲取數據庫鏈接。
     *
     * @throws Exception
     */
    @Test
    public void test18() throws Exception {
        Properties properties = new Properties();
        InputStream in = JdbcTest.class.getClassLoader().getResourceAsStream("dbcp.properties");
        properties.load(in);

        DataSource dataSource = BasicDataSourceFactory.createDataSource(properties);

        //BasicDataSource basicDataSource = (BasicDataSource) dataSource;
    }

3、C3P0 數據庫鏈接池

(1)基本用法函數

(2)更好的用法性能

/**
	 * 1. 建立 c3p0-config.xml 文件, 
	 * 參考幫助文檔中 Appendix B: Configuation Files 的內容
	 * 2. 建立 ComboPooledDataSource 實例;
	 * DataSource dataSource = 
	 *			new ComboPooledDataSource("helloc3p0");  
	 * 3. 從 DataSource 實例中獲取數據庫鏈接. 
	 */
	@Test
	public void testC3poWithConfigFile() throws Exception{
		DataSource dataSource = 
				new ComboPooledDataSource("helloc3p0");  
		
		System.out.println(dataSource.getConnection()); 
		
		ComboPooledDataSource comboPooledDataSource = 
				(ComboPooledDataSource) dataSource;
		System.out.println(comboPooledDataSource.getMaxStatements()); 
	}

附c3p0-config.xml:學習

<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>

	<named-config name="helloc3p0">
		
		<!-- 指定鏈接數據源的基本屬性 -->
		<property name="user">root</property>
		<property name="password">1230</property>
		<property name="driverClass">com.mysql.jdbc.Driver</property>
		<property name="jdbcUrl">jdbc:mysql:///atguigu</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>

 

 

JDBC學習筆記:大數據

1. 獲取數據庫鏈接    http://my.oschina.net/daowuming/blog/704243

2. 經過Statement執行更新、查詢操做    http://my.oschina.net/daowuming/blog/704384

3. 使用PrepareStatement    http://my.oschina.net/daowuming/blog/704432

4. 使用ResultSetMetaData 對象處理結果集元數據    http://my.oschina.net/daowuming/blog/704487

5. 使用DatabaseMetaData獲取數據庫信息    http://my.oschina.net/daowuming/blog/704553

6. BLOB    http://my.oschina.net/daowuming/blog/704593

7. 處理事務與隔離級別    http://my.oschina.net/daowuming/blog/704611

8. 批量處理    http://my.oschina.net/daowuming/blog/704641

9. 數據庫鏈接池    ----當前----

10. 調用函數與存儲過程    http://my.oschina.net/daowuming/blog/704813

相關文章
相關標籤/搜索