如果想要搭建一個高效的網站,鏈接池是必須用到的一部分。而連接池的選擇是多種多樣的。就現在的軟件開發界而言,最為多用的是DBCP, c3p0, 和 proxool。而hibernate推薦使用的是c3p0 和proxool,並且宣布不再支持DBCP。 因此,重點就是如果想要在自己的應用程序中加入數據庫連接池,就必須掌握其中的一種,而最好得選擇就是c3p0和proxool中的任何一種。
下面來說說數據庫連接池的相關概念和基本原理,以便於讀者更加容易的理解后邊的實際應用。
使用過數據庫操作的人都知道,當我們需要進行數據庫操作時,首先需要對數據庫進行連接,然后執行操作,再然后我們使用完畢后需要將數據庫關閉。如果在使用后沒有關閉數據庫連接,那么,這個連接就一直在占用狀態。當使用的人數增加,連接也增加,系統會很快就崩潰。在超過負荷之后直接down掉!!!這就是在程序中沒有及時的關閉數據庫連接的危害。但是,這種每使用一次就連接和關閉一次數據庫連接其實際上是對數據庫有一定的影響的。因此,才有了數據庫連接池的概念。
數據庫連接池實際上就是在程序加載時就按照設置的數量先和數據庫建立一定量的連接,當需要數據庫連接時就直接從最開始建立的連接中取得所需要的連接就行。當不需要時,只需要將連接還給連接池;當建立的連接被取用完后,並且還存在后續的請求,也就是說現在的連接數量已經超過了系統設置的最大連接數。那么,后面的請求只有等待!!
百度給出的解釋是:
作者:itRed 郵箱:it_red@sina.com 博客:http://www.cnblogs.com/itred
在進行正式開放之前,了解一下幾個專用術語:
maximum-connection-count:最大連接數(默認5個),超過了這個連接數,再有請求時,就排在隊列中等候,最大的等待請求數由maximum-new-connections決定
minimum-connection-count:最小連接數(默認2個)
house-keeping-sleep-time:proxool自動偵察各個連接狀態的時間間隔(毫秒),偵察到空閑的連接就馬上回收,超時的銷毀 默認30秒
maximum-new-connections:沒有空閑連接可以分配而在隊列中等候的最大請求數,超過這個請求數的用戶連接就不會被接受
prototype-count :最少保持的空閑連接數(默認2個)
test-before-use:在使用之前測試
house-keeping-test-sql:用於保持連接的測試語句
好了!看看具體的實例應用就會明白以上所說的相關概念了。本人按java和web工程來敘述案例,需要聲明一下,proxool的應用是沒有固定的形式了。並不是只能在java中應用它的xml形式。它的配置可以以任何形式運行。具體的看它的官方文檔。本人主要以理解為首,開發為主。因此以web和java工程區分。
先說一下數據庫的數據
Demo 1. 在java工程中添加proxool連接池
一.新建java工程,在目錄下直接見一個lib包,用來存放項目工程所有的jar包,導入相關的jar包,然后build path。利用proxool實現連接池的jar包如下:
二. 在src目錄下新家一個測試包,附加一個測試類Test.java:
包名:com.red.test
Test.java的源碼如下:

package com.red.test; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.Statement; import org.logicalcobwebs.proxool.configuration.JAXPConfigurator; public class Test { public static void main(String[] args) throws Exception { Test obj = new Test(); obj.test2(); } int beginIndex = 0; int endIndex = 10; //取10條記錄 String MySQLdbTableName = "user"; String MySQLreq = "select * from " + MySQLdbTableName + " limit " + beginIndex + ", " + endIndex; public void test2() throws Exception { // Java應用中先要加載配置文件,否則誰知道你配置給誰用的 JAXPConfigurator.configure("src/proxool.xml", false); // 1:注冊驅動類,這次這個驅動已經不是Oracle的驅動了,是Proxool專用的驅動 Class.forName("org.logicalcobwebs.proxool.ProxoolDriver"); // 2:創建數據庫連接,這個參數是一個字符串,是數據源的別名,在配置文件中配置的timalias,參數格式為:proxool.數據源的別名 Connection conn = DriverManager.getConnection("proxool.mysql"); for (int i = 0; i < 20; i++) conn = DriverManager.getConnection("proxool.mysql"); Statement stmt = conn.createStatement(); ResultSet res = stmt.executeQuery(MySQLreq); ResultSetMetaData rsmd = res.getMetaData(); int columnCount = rsmd.getColumnCount(); int rowCount = 0; while (res.next()) { System.out.print(rowCount + " "); rowCount++; for (int j = 1; j <= columnCount; j++) { String strRes = res.getString(j); System.out.print(strRes + "|\t"); } System.out.println(); } conn.close(); } }
三. 在src目錄下新建一個xml文件。在這個文件中配置項目與數據庫的連接。源碼如下:
Proxool.xml源碼:

<?xml version="1.0" encoding="UTF-8"?> <something-else-entirely> <proxool> <alias>mysql</alias> <driver-url>jdbc:mysql://127.0.0.1:3306/test</driver-url> <driver-class>com.mysql.jdbc.Driver</driver-class> <driver-properties> <property name="user" value="root" /> <property name="password" value="123456" /> </driver-properties> <!-- 最大連接數(默認5個),超過了這個連接數,再有請求時,就排在隊列中等候,最大的等待請求數由maximum-new-connections決定 --> <maximum-connection-count>30</maximum-connection-count> <!--最小連接數(默認2個)--> <minimum-connection-count>1</minimum-connection-count> <!--proxool自動偵察各個連接狀態的時間間隔(毫秒),偵察到空閑的連接就馬上回收,超時的銷毀 默認30秒--> <house-keeping-sleep-time>90000</house-keeping-sleep-time> <!--沒有空閑連接可以分配而在隊列中等候的最大請求數,超過這個請求數的用戶連接就不會被接受--> <maximum-new-connections>6</maximum-new-connections> <!--最少保持的空閑連接數(默認2個)--> <prototype-count>5</prototype-count> <!--在使用之前測試--> <test-before-use>true</test-before-use> <!--用於保持連接的測試語句 --> <house-keeping-test-sql>show tables</house-keeping-test-sql> </proxool> </something-else-entirely>
四. 運行結果:
Demo 2. 在java web 項目下使用proxool數據庫連接池:
一.新建web工程,導入jar包。過程同上;
二.在src目錄下新建兩個包,分別是放數據庫連接的,還有一個包用來存放測試用的文件。在src目錄下新建一個properties文件。
包名:com.red.proxool 目錄下的ConnectFactory.java文件 源碼:

package com.red.proxool; import java.io.IOException; import java.io.InputStream; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.sql.Statement; import java.util.Properties; import org.logicalcobwebs.proxool.ProxoolException; import org.logicalcobwebs.proxool.configuration.PropertyConfigurator; public class ConnectFactory { private static ConnectFactory connectFactory = null; private static String defaultaliasname = "test"; public ConnectFactory() { } private ConnectFactory(String name) { init(); } public static ConnectFactory getInstance() { if (null == connectFactory) { connectFactory = new ConnectFactory(defaultaliasname); } return connectFactory; } public Connection getConnect() { try { Connection conn = DriverManager.getConnection("proxool." + defaultaliasname); return conn; } catch (SQLException e) { e.printStackTrace(); } return null; } public Connection getConnect(String aliasname) { try { Connection conn = DriverManager.getConnection("proxool." + aliasname); return conn; } catch (SQLException e) { e.printStackTrace(); } return null; } private static void init() { try { InputStream is = new ConnectFactory().getClass().getResourceAsStream("/proxool.properties"); Properties properties = new Properties(); properties.load(is); PropertyConfigurator.configure(properties); } catch (IOException e) { e.printStackTrace(); } catch (ProxoolException e1) { e1.printStackTrace(); } } public static void closeConnects(Connection conn, Statement state) { try { if (null != state && !conn.isClosed()) conn.close(); if (null != state && !state.isClosed()) state.close(); } catch (SQLException e) { e.printStackTrace(); } } }
包名:com.red.test目錄下的Test.java文件 源碼:

package com.red.test; import java.sql.ResultSet; import java.sql.SQLException; import com.mysql.jdbc.Connection; import com.mysql.jdbc.Statement; import com.red.proxool.ConnectFactory; public class Test { static ConnectFactory connectionFactory= null; public static void main(String[] args) { connectionFactory = new ConnectFactory(); Connection conn = (Connection) ConnectFactory.getInstance() .getConnect(); String sql = "SELECT * FROM test.user"; Statement stmt = null; ResultSet rs = null; try { stmt = (Statement) conn.createStatement(); rs = stmt.executeQuery(sql); while (rs.next()) { System.out.println("[ " + rs.getString(2) + " ]"); } } catch (SQLException e) { e.printStackTrace(); } finally { ConnectFactory.closeConnects(conn, stmt); } } }
Src目錄下的proxool.properties文件 源碼:

jdbc-1.proxool.alias=test jdbc-1.proxool.driver-class=com.mysql.jdbc.Driver jdbc-1.proxool.driver-url=jdbc:mysql://127.0.0.1:3306?useUnicode=true&characterEncoding=utf8 jdbc-1.user=root jdbc-1.password=123456 jdbc-1.proxool.maximum-connection-count=50 jdbc-1.proxool.minimum-connection-count=5 jdbc-1.proxool.prototype-count=4 jdbc-1.proxool.house-keeping-test-sql=select now(); jdbc-1.proxool.verbose=true jdbc-1.proxool.statistics=10s,1m,1d jdbc-1.proxool.statistics-log-level=ERROR jdbc-2.proxool.alias=local jdbc-2.proxool.driver-class=com.mysql.jdbc.Driver jdbc-2.proxool.driver-url=jdbc:mysql://127.0.0.1:3306?useUnicode=true&characterEncoding=utf8 jdbc-2.user=root jdbc-2.password=123456 jdbc-2.proxool.maximum-connection-count=50 jdbc-2.proxool.minimum-connection-count=2 jdbc-2.proxool.prototype-count=4 jdbc-2.proxool.house-keeping-test-sql=select now(); jdbc-2.proxool.verbose=true jdbc-2.proxool.statistics=10s,1m,1d jdbc-2.proxool.statistics-log-level=ERROR
三.正如proxool.properties設置的一樣。其中可以有兩個或兩個以上的數據庫。本文用了兩個。更多地情況,讀者可以自己嘗試。
調用時只需要將它的別名作為參數就行。
public Connection getConnect(String aliasname)
四. 測試運行結果:
我相信通過以上兩個例子,你應該對proxool連接池有了更深入的認識。本人只是希望這篇博客能夠給剛接觸proxool連接池的菜鳥朋友起一個拋磚引玉的作用。個人感覺只要這兩個案例程序調試出來了,基本上在程序開發的過程中也就夠用了。如果喜歡或者希望更加深入的理解proxool連接池還是需要去詳細的閱讀它的API文檔。另外歡迎大神拍磚指教!
本文源碼下載
作者:itRed 郵箱:it_red@sina.com 博客:http://www.cnblogs.com/itred
版權聲明:本文版權歸作者和博客園共有,歡迎轉載,但請在文章顯眼位置標明文章出處。未經本人書面同意,將其作為他用,本人保留追究責任的所有權利。
了解一下幾個專用術語: