JDBC 資料庫連接池,jdbc資料庫連接池
必要的文字描述:
JDBC資料庫連接池的必要性:
在使用開發基於資料庫的web程式時,傳統的模式基本是按以下步驟:
在主程式(如servlet、beans)中建立資料庫連接。
進行sql操作
斷開資料庫連接。
這種模式開發,存在的問題:
普通的JDBC資料庫連接使用 DriverManager 來擷取,每次向資料庫建立串連的時候都要將
Connection 載入到記憶體中,再驗證使用者名稱和密碼(得花費0.05s~1s的時間)。需要資料
庫串連的時候,就向資料庫要求一個,執行完成後再中斷連線。這樣的方式將會消耗大
量的資源和時間。資料庫的串連資源並沒有得到很好的重複利用.若同時有幾百人甚至幾
千人線上,頻繁的進行資料庫連接操作將佔用很多的系統資源,嚴重的甚至會造成伺服器的崩潰。
對於每一次資料庫連接,使用完後都得斷開。否則,如果程式出現異常而未能關閉,將會導致資料庫
系統中的記憶體流失,最終將導致重啟資料庫。
這種開發不能控制被建立的連線物件數,系統資源會被毫無顧及的分配出去,如串連過多,
也可能導致記憶體流失,伺服器崩潰。
資料庫連接池:
為解決傳統開發中的資料庫連接問題,可以採用資料庫連接池技術。
資料庫連接池的基本思想就是為資料庫連接建立一個“緩衝池”。預先在
緩衝池中放入一定數量的串連,當需要建立資料庫連接時,只需從“緩衝池”
中取出一個,使用完畢之後再放回去。
資料庫連接池負責分配、管理和釋放資料庫連接,它允許應用程式重複使
用一個現有的資料庫連接,而不是重建立立一個。
資料庫連接池在初始化時將建立一定數量的資料庫連接放到串連池中,這些
資料庫連接的數量是由最小資料庫連接數來設定的。無論這些資料庫連接是
否被使用,串連池都將一直保證至少擁有這麼多的串連數量。串連池的最大
資料庫連接數量限定了這個串連池能佔有的最大串連數,當應用程式向串連
池請求的串連數超過最大串連數量時,這些請求將被加入到等待隊列中。
資料庫連接池技術的優點:
資源重用:
由於資料庫連接得以重用,避免了頻繁建立,釋放串連引起的大量效能開銷。
在減少系統消耗的基礎上,另一方面也增加了系統運行環境的平穩性。
更快的系統反應速度:
資料庫連接池在初始化過程中,往往已經建立了若干資料庫連接置於串連池
中備用。此時串連的初始化工作均已完成。對於業務請求處理而言,直接利
用現有可用串連,避免了資料庫連接初始化和釋放過程的時間開銷,從而減
少了系統的回應時間
新的資源分派手段:
對於多應用共用同一資料庫的系統而言,可在應用程式層通過資料庫連接池的配置,
實現某一應用最大可用資料庫連接數的限制,避免某一應用獨佔所有的資料庫資源
統一的串連管理,避免資料庫連接泄露
在較為完善的資料庫連接池實現中,可根據預先的佔用逾時設定,強制回收被佔用
串連,從而避免了常規資料庫連接操作中可能出現的資源流失
以下介紹兩種開源的資料庫連接池:DBCP C3P0
JDBC 的資料庫連接池使用 javax.sql.DataSource 來表示,DataSource 只是一個介面,
該介面通常由伺服器(Weblogic, WebSphere, Tomcat)提供實現,也有一些開源組織提供實現:
DBCP 資料庫連接池
C3P0 資料庫連接池
DataSource 通常被稱為資料來源,它包含串連池和串連池管理兩個部分,習慣上也經常把
DataSource 稱為串連池
DBCP 是 Apache 軟體基金組織下的開源串連池實現,該串連池依賴該組織下的另一個開源系統:
Common-pool. 如需使用該串連池實現,應在系統中增加如下兩個 jar 檔案:
Commons-dbcp.jar:串連池的實現
Commons-pool.jar:串連池實現的依賴庫
Tomcat 的串連池正是採用該串連池來實現的。該資料庫連接池既可以與應用伺服器整合使用,也可由應用程式獨立使用。
DBCP 資料來源使用範例:
資料來源和資料庫連接不同,資料來源無需建立多個,它是產生資料庫連接的工廠,因此整個應用只需要一個
資料來源即可。
當資料庫訪問結束後,程式還是像以前一樣關閉資料庫連接:conn.close(); 但上面的代碼並沒有關閉資料庫的物理串連,
它僅僅把資料庫連接釋放,歸還給了資料庫連接池。
DBCP簡單的代碼案例 資料庫連接池的串連方式:
/* * 檔案名稱:DbcpTest.java * 著作權:Copyright by www.huawei.com * 描述: * 修改人:Cuigaochong * 修改時間:2015-8-27 * 跟蹤單號: * 修改單號: * 修改內容: */package com.jdbc.dbcp;import java.io.IOException;import java.io.InputStream;import java.sql.Connection;import java.sql.SQLException;import java.util.Properties;import org.apache.commons.dbcp.BasicDataSource;import org.apache.commons.dbcp.BasicDataSourceFactory;import org.junit.Test;/** * <一句話功能簡述> <功能詳細描述> * * @author 姓名 工號 * @version [版本號碼, 2015-8-27] * @see [相關類/方法] * @since [產品/模組版本] */public class DbcpTest{ @Test public void test01() throws SQLException { BasicDataSource dataSource = null; dataSource = new BasicDataSource(); // 資料來源串連必須的屬性 dataSource.setUsername("scott"); dataSource.setPassword("tiger"); dataSource.setUrl("jdbc:oracle:thin:@localhost:1521:oracl"); dataSource.setDriverClassName("oracle.jdbc.driver.OracleDriver"); // 資料庫連接池的屬性 // 指定資料連線池中初始化的串連個數 dataSource.setInitialSize(10); // 指定資料庫連接池最大的串連數 dataSource.setMaxActive(50); // 指定最少串連數,在資料庫連接池中儲存的最少的空閑串連數量 dataSource.setMinIdle(5); // 等待資料庫連接池串連的最長時間 單位ms 超過最長時間將拋出異常 dataSource.setMaxWait(5 * 1000); Connection conn = dataSource.getConnection(); System.out.println(conn); } /** * <一句話功能簡述>方法二相對一方法而言更加好 因為可以把屬性全部放在jdbc.properyies檔案中 * ,並且開發人員不需要關心DataSource的實現,只需要從工廠類中擷取 <功能詳細描述> * * @see [類、類#方法、類#成員] */ @Test public void test02() { Properties properties = new Properties(); InputStream is = null; BasicDataSource dataSource = null; Connection conn = null; try { is = getClass().getClassLoader().getResourceAsStream("jdbc.properties"); properties.load(is); dataSource = (BasicDataSource)BasicDataSourceFactory.createDataSource(properties); conn = dataSource.getConnection(); //可以直接通過dataSource 擷取jdbc.properties中的配置值 System.out.println(dataSource.getMaxActive()); } catch (Exception e) { e.printStackTrace(); } finally { if (null != conn) { try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } if (null != is) { try { is.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
C3P0資料來源 系統添加c3p0-0.9.1.2.jar
步驟:1:建立c3p0-config.xml 內容如下
<c3p0-config>
<!-- This app is massive! -->
<named-config name="intergalactoApp">
<property name="user">scott</property>
<property name="password">tiger</property>
<property name="driverClass">oracle.jdbc.driver.OracleDriver</property>
<property name="jdbcUrl">jdbc:oracle:thin:@localhost:1521:oracl</property>
<property name="acquireIncrement">5</property>
<property name="initialPoolSize">10</property>
<property name="minPoolSize">5</property>
<property name="maxPoolSize">10</property>
<!-- c3p0可以維護的statement的數量 -->
<property name="maxStatements">0</property>
<!-- 每個串連可以使用的statement的數量 -->
<property name="maxStatementsPerConnection">5</property>
</named-config>
</c3p0-config>
2:建立ComboPooledDataSource執行個體,
ComboPooledDataSource cpds = new ComboPooledDataSource("intergalactoApp");
3:擷取串連
Connection conn = cpds.getConnection();
案例代碼 擷取串連:
/* * 檔案名稱:C3p0Test.java * 著作權:Copyright by www.huawei.com * 描述: * 修改人:Cuigaochong * 修改時間:2015-8-27 * 跟蹤單號: * 修改單號: * 修改內容: */package com.jdbc.dbcp;import java.beans.PropertyVetoException;import java.sql.Connection;import java.sql.SQLException;import org.junit.Test;import com.mchange.v2.c3p0.ComboPooledDataSource;/** * <一句話功能簡述> <功能詳細描述> * * @author 姓名 工號 * @version [版本號碼, 2015-8-27] * @see [相關類/方法] * @since [產品/模組版本] */public class C3p0Test{ @Test public void test00() throws PropertyVetoException, SQLException { ComboPooledDataSource cpds = new ComboPooledDataSource(); cpds.setDriverClass("oracle.jdbc.driver.OracleDriver"); cpds.setJdbcUrl("jdbc:oracle:thin:@localhost:1521:oracl"); cpds.setUser("scott"); cpds.setPassword("tiger"); Connection conn = cpds.getConnection(); System.out.println(conn); } @Test public void test01() throws SQLException { // intergalactoApp 為設定檔中的<named-config name="intergalactoApp"> // 設定檔可以是xml 也可以是properties建議使用xml,xml的命名只能是c3p0-config.xml ComboPooledDataSource cpds = new ComboPooledDataSource("intergalactoApp"); Connection conn = cpds.getConnection(); System.out.println(conn); // 擷取設定檔中的屬性 System.out.println(cpds.getMaxPoolSize()); } }
著作權聲明:本文為博主原創文章,未經博主允許不得轉載。