復習數據庫連接池 : C3P0、DBCP
1、數據庫連接池技術的優點:
•資源重用:
由於數據庫連接得以重用,避免了頻繁創建,釋放連接引起的大量性能開銷。在減少系統消耗的基礎上,另一方面也增加了系統運行環境的平穩性。
•更快的系統反應速度:
數據庫連接池在初始化過程中,往往已經創建了若干數據庫連接置於連接池中備用。此時連接的初始化工作均已完成。對於業務請求處理而言,直接利用現有可用連接,避免了數據庫連接初始化和釋放過程的時間開銷,從而減少了系統的響應時間。
•新的資源分配手段:
對於多應用共享同一數據庫的系統而言,可在應用層通過數據庫連接池的配置,實現某一應用最大可用數據庫連接數的限制,避免某一應用獨占所有的數據庫資源。
•統一的連接管理,避免數據庫連接泄露:
在較為完善的數據庫連接池實現中,可根據預先的占用超時設定,強制回收被占用連接,從而避免了常規數據庫連接操作中可能出現的資源泄露。
1)兩種開源的數據庫連接池:
• JDBC 的數據庫連接池使用 javax.sql.DataSource 來表示,DataSource 只是一個接口,
該接口通常由服務器(Weblogic, WebSphere, Tomcat)提供實現,也有一些開源組織提供實現:
–
DBCP 數據庫連接池
–
C3P0 數據庫連接池
• DataSource 通常被稱為數據源,它包含連接池和連接池管理兩個部分,習慣上也經常把 DataSource 稱為連接池
A:DBCP 數據源 :
• DBCP 是 Apache 軟件基金組織下的開源連接池實現,該連接池依賴該組織下的另一個開源系統:Common-pool. 如需使用該連接池實現,應在系統中增加如下兩個 jar 文件:
–
Commons-dbcp.jar:連接池的實現。
–
Commons-pool.jar:連接池實現的依賴庫。
•
Tomcat 的連接池正是采用該連接池來實現的。該數據庫連接池既可以與應用服務器整合使用,也可由應用程序獨立使用。
DBCP 數據源使用范例:
• 數據源和數據庫連接不同,數據源無需創建多個,它是產生數據庫連接的工廠,因此整個應用只需要一個數據源即可。
• 當數據庫訪問結束后,程序還是像以前一樣關閉數據庫連接:conn.close(); 但上面的代碼並沒有關閉數據庫的物理連接,它僅僅把數據庫連接釋放,歸還給了數據庫連接池。

/** * 1. 加載 dbcp 的 properties 配置文件: 配置文件中的鍵需要來自 BasicDataSource * 的屬性. * 2. 調用 BasicDataSourceFactory 的 createDataSource 方法創建 DataSource * 實例 * 3. 從 DataSource 實例中獲取數據庫連接. */ @Test public void testDBCPWithDataSourceFactory() throws Exception{ Properties properties = new Properties(); InputStream inStream = JDBCTest.class.getClassLoader() .getResourceAsStream("dbcp.properties"); properties.load(inStream); DataSource dataSource = BasicDataSourceFactory.createDataSource(properties); System.out.println(dataSource.getConnection()); // BasicDataSource basicDataSource = // (BasicDataSource) dataSource; // // System.out.println(basicDataSource.getMaxWait()); } /** * 使用 DBCP 數據庫連接池 * 1. 加入 jar 包(2 個jar 包). 依賴於 Commons Pool * 2. 創建數據庫連接池 * 3. 為數據源實例指定必須的屬性 * 4. 從數據源中獲取數據庫連接 * @throws SQLException */ @Test public void testDBCP() throws SQLException{ final BasicDataSource dataSource = new BasicDataSource(); //2. 為數據源實例指定必須的屬性 dataSource.setUsername("root"); dataSource.setPassword("1230"); dataSource.setUrl("jdbc:mysql:///atguigu"); dataSource.setDriverClassName("com.mysql.jdbc.Driver"); //3. 指定數據源的一些可選的屬性. //1). 指定數據庫連接池中初始化連接數的個數 dataSource.setInitialSize(5); //2). 指定最大的連接數: 同一時刻可以同時向數據庫申請的連接數 dataSource.setMaxActive(5); //3). 指定小連接數: 在數據庫連接池中保存的最少的空閑連接的數量 dataSource.setMinIdle(2); //4).等待數據庫連接池分配連接的最長時間. 單位為毫秒. 超出該時間將拋出異常. dataSource.setMaxWait(1000 * 5); //4. 從數據源中獲取數據庫連接 Connection connection = dataSource.getConnection(); System.out.println(connection.getClass()); connection = dataSource.getConnection(); System.out.println(connection.getClass()); connection = dataSource.getConnection(); System.out.println(connection.getClass()); connection = dataSource.getConnection(); System.out.println(connection.getClass()); Connection connection2 = dataSource.getConnection(); System.out.println(">" + connection2.getClass()); new Thread(){ public void run() { Connection conn; try { conn = dataSource.getConnection(); System.out.println(conn.getClass()); } catch (SQLException e) { e.printStackTrace(); } }; }.start(); try { Thread.sleep(5500); } catch (InterruptedException e) { e.printStackTrace(); } connection2.close(); }

username=root password=1230 driverClassName=com.mysql.jdbc.Driver url=jdbc:mysql:///atguigu initialSize=10 maxActive=50 minIdle=5 maxWait=5000
B:C3P0 數據源

/** * 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()); } @Test public void testC3P0() throws Exception{ ComboPooledDataSource cpds = new ComboPooledDataSource(); cpds.setDriverClass( "com.mysql.jdbc.Driver" ); //loads the jdbc driver cpds.setJdbcUrl( "jdbc:mysql:///atguigu" ); cpds.setUser("root"); cpds.setPassword("1230"); System.out.println(cpds.getConnection()); }

<?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>
(待續。。。)