若是想要搭建一個高效的網站,連接池是必須用到的一部分。而鏈接池的選擇是多種多樣的。就如今的軟件開發界而言,最爲多用的是DBCP, c3p0, 和 proxool。而hibernate推薦使用的是c3p0 和proxool,而且宣佈再也不支持DBCP。 所以,重點就是若是想要在本身的應用程序中加入數據庫鏈接池,就必須掌握其中的一種,而最好得選擇就是c3p0和proxool中的任何一種。java
下面來講說數據庫鏈接池的相關概念和基本原理,以便於讀者更加容易的理解後邊的實際應用。mysql
使用過數據庫操做的人都知道,當咱們須要進行數據庫操做時,首先須要對數據庫進行鏈接,而後執行操做,再而後咱們使用完畢後須要將數據庫關閉。若是在使用後沒有關閉數據庫鏈接,那麼,這個鏈接就一直在佔用狀態。當使用的人數增長,鏈接也增長,系統會很快就崩潰。在超過負荷以後直接down掉!!!這就是在程序中沒有及時的關閉數據庫鏈接的危害。可是,這種每使用一次就鏈接和關閉一次數據庫鏈接其其實是對數據庫有必定的影響的。所以,纔有了數據庫鏈接池的概念。web
數據庫鏈接池實際上就是在程序加載時就按照設置的數量先和數據庫創建必定量的鏈接,當須要數據庫鏈接時就直接從最開始創建的鏈接中取得所須要的鏈接就行。當不須要時,只須要將鏈接還給鏈接池;當創建的鏈接被取用完後,而且還存在後續的請求,也就是說如今的鏈接數量已經超過了系統設置的最大鏈接數。那麼,後面的請求只有等待!!sql
百度給出的解釋是:數據庫
做者:itRed 郵箱:it_red@sina.com 博客:http://www.cnblogs.com/itredapp
在進行正式開放以前,瞭解一下幾個專用術語:ide
maximum-connection-count:最大鏈接數(默認5個),超過了這個鏈接數,再有請求時,就排在隊列中等候,最大的等待請求數由maximum-new-connections決定測試
minimum-connection-count:最小鏈接數(默認2個)網站
house-keeping-sleep-time:proxool自動偵察各個鏈接狀態的時間間隔(毫秒),偵察到空閒的鏈接就立刻回收,超時的銷燬 默認30秒ui
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
版權聲明:本文版權歸做者和博客園共有,歡迎轉載,但請在文章顯眼位置標明文章出處。未經本人書面贊成,將其做爲他用,本人保留追究責任的全部權利。
瞭解一下幾個專用術語: