目前有多重方式創建數據庫連接池:JNDI,DBCP,C3P0等
為什么需要連接池:
使用java API DriverManager.getConnection()創建數據庫連接,耗費內存和時間,實時性低;這種方式獲取的connection需要手動關閉,不然會耗費大量的內存資源;對於頻繁數據庫操作,這種方式會造成性能低,尤其web應用
數據庫連接池的功能:
負責創建、管理和分配數據庫連接。初始化數據庫連接池時,會創建一定數量的數據庫連接對象,並存放於數據庫連接池中。當請求連接數據庫時,連接池會分配處於空閑狀態的連接;數據庫連接不被使用時,會被連接池回收,並設置為空閑狀態;當連接空閑時間大於在初始化連接池設定的連接空閑時間,連接池釋放該連接。
數據庫連接池介紹:
1、 JNDI
2、 C3p0
3、 Apache的Jakarta DBCP
4、 BoneCP
其中,sping框架依賴的第三方使用了c3p0和dbcp兩種方式;而bonecp號稱是速度最快的數據庫連接池。JNDI方式創建實現的datasource是真正實現了javax.sql.datasource;其他的三種方式都不是。下面的列表,列出了幾種方式的區別和不同:
序號 |
連接池名稱 |
依賴的jar包 |
實現的datasource類 |
備注 |
1 |
JNDI |
該數據源是由相應的web服務器(例如:tomcat,weblogic,websphere)負責初始化,創建,管理。程序中不需要引入特別的jar包。 |
Javax.sql.datasource |
|
2 |
C3P0 |
c3p0-0.9.xxx.jar |
com.mchange.v2.c3p0.ComboPooledDataSource |
|
3 |
DBCP |
commons-dbcp.jar,commons-pool.jar |
org.apache.commons.dbcp.BasicDataSource |
|
4 |
BoneCP
|
bonecp-0.6.5.jar · google-collections-1.0.jar · slf4j-api-1.5.11.jar · slf4j-log4j12-1.5.11.jar ·log4j-1.2.15.jar
|
BoneCPDataSource |
|
備注:以上幾種方式的數據庫連接池的配置參數大同小異,略有差別;其參數的配置,既可以通過配置文件的方式配置,也可以通過硬編碼的方式配置。
1,使用JNDI方式
這種方式,是由web服務器實現了java.sql.datasource。由web服務器負責初始化數據源,創建connection,分配,管理connection。由於本身是由web服務器實現的功能,因此不需要在項目project中引入特別的jar包,但是需要在服務器的某些配置文件中增加相關的配置。下面,以tomcat服務器為例,講述這種方式的使用。
(1)、修改tomcat的conf下的context.xml文件,增加Resource的配置的支持。
(2)、由於數據源是由tomcat負責創建,所以需要的jdbc驅動應該放到tomcat的lib路徑下。
(3)、編寫使用java代碼,並放在tomcat環境下使用,如下:
public void jnditest(){
// TODO Auto-generated method stub
try {
Context initcontext=new InitialContext();
Context context=(Context) initcontext.lookup("java:comp/env");
DataSource datasource=(DataSource)context.lookup("jdbc/editortest");
Connection cn=datasource.getConnection();
Statement st=cn.createStatement();
String sql="select * from artical where id=1";
ResultSet rs=st.executeQuery(sql);
while(rs.next()){
System.out.println("1:"+rs.getString(1));
System.out.println("2:"+rs.getString(2));
System.out.println("3:"+rs.getString(3));
System.out.println("4:"+rs.getString(4));
}
} catch (NamingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
(4)、詳情參考jndisql。Java文件,以及index.jsp。
注意:該測試不能在main方法中測試;可以寫一個jsp在tomcat環境中測試。因為:java單元的環境是jdk;而jsp的環境卻是tomcat;數據連接池是在tomcat中配置的,所以能正常運行的,但java測試的環境只有jdk,所以在引用數據連接池時就時出現找不到環境的錯誤。
使用環境:當使用weblogic或者websphere等高級的web服務器的時候,可以考慮使用這種方式提高性能。
3、 使用C3p0方式
C3P0是開源的數據庫連接組件,支持創建數據庫連接池,管理connection等功能。使用該種方式做數據庫連接時候,需要導入c3p0-0.9.1.2.jar。
同時,關於數據庫連接的具體參數,例如:url,username,password,最小連接數,最大連接數。。。。。等信息既可以在xml配置文件中配置,也可以通過程序編碼方式創建。Spring支持c3p0的數據庫連接池方式,因此在spring環境中使用時,支持在applicationcontext.xml文件中配置。另外,由於數據庫連接池在整個project中針對某個數據庫而言是單例的,所以,即使通過編碼的方式創建,那么要保證其單實例特性。如果存在多個,那么必然會導致性能低下。
下面,列出通過程序編碼方式使用c3p0數據庫連接池的方式。
ComboPooledDataSource ds = new ComboPooledDataSource();
try {
ds.setDriverClass("com.mysql.jdbc.Driver");
ds.setJdbcUrl("jdbc:mysql://localhost:3306/editortest");
ds.setUser("root");
ds.setPassword("123456");
ds.setMaxPoolSize(20);
ds.setInitialPoolSize(10);
ds.setMaxIdleTime(2000);
Connection cn=ds.getConnection();
Statement st=cn.createStatement();
String sql="select * from artical where id=1";
ResultSet rs=st.executeQuery(sql);
while(rs.next()){
System.out.println("1:"+rs.getString(1));
System.out.println("2:"+rs.getString(2));
System.out.println("3:"+rs.getString(3));
System.out.println("4:"+rs.getString(4));
}
} catch (PropertyVetoException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
備注:通常使用方式,都是通過配置文件配置,幾乎不會用到這種硬編碼方式。在此,只是簡單介紹C3P0的使用方式。詳情,可以參考c3p0test.java。
4、 使用dbcp方式
DBCP方式,是apache提供的數據源連接池方式,支持數據庫連接池創建,管理connection等功能。使用環境,需要導入commons-dbcp.jar 和 commons-pool.jar兩個jar包。上面提到的JNDI方式,其實質實用的就是dbcp數據源;只是他是通過在web服務器上做配置,由web服務器負責創建該數據源。
同樣的,dbcp數據源也支持xml配置文件和硬編碼兩種方式。通常使用方式,都是通過配置文件配置,幾乎不會使用硬編碼方式。下面簡單介紹dbcp方式的編碼:
BasicDataSource ds = new BasicDataSource();
ds.setDriverClassName("com.mysql.jdbc.Driver");
ds.setUrl("jdbc:mysql://localhost:3306/editortest");
ds.setUsername("root");
ds.setPassword("123456");
ds.setMaxIdle(20);
ds.setInitialSize(10);
ds.setMaxActive(2000);
try {
Connection cn=ds.getConnection();
Statement st=cn.createStatement();
String sql="select * from artical where id=1";
ResultSet rs=st.executeQuery(sql);
while(rs.next()){
System.out.println("1:"+rs.getString(1));
System.out.println("2:"+rs.getString(2));
System.out.println("3:"+rs.getString(3));
System.out.println("4:"+rs.getString(4));
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
5、 使用BoneCP方式。
BoneCP是快速高效的數據庫連接池組件,據說性能上目前是最好得,比C3P0和DBCP快25倍。使用該組件,需要導入bonecp-0.6.5.jar,google-collections-1.0.jar,slf4j-api-1.5.11.jar,slf4j-log4j12-1.5.11.jar,log4j-1.2.15.jar。
下面,簡單列出編碼方式的使用,做簡單的了解。
BoneCPDataSource ds = new BoneCPDataSource();
ds.setDriverClass("com.mysql.jdbc.Driver");
ds.setJdbcUrl("jdbc:mysql://localhost:3306/editortest");
ds.setUsername("root");
ds.setPassword("123456");
try {
Connection cn = ds.getConnection();
Statement st = cn.createStatement();
String sql = "select * from artical where id=1";
ResultSet rs = st.executeQuery(sql);
while (rs.next()) {
System.out.println("1:" + rs.getString(1));
System.out.println("2:" + rs.getString(2));
System.out.println("3:" + rs.getString(3));
System.out.println("4:" + rs.getString(4));
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
總結:以上,介紹了幾種常用的數據源連接池;這幾種連接池在使用過程,即支持硬編碼的方式,也支持配置文件的配置方式;在正式實用的時候,應該盡量使用配置的方式,便於維護和管理。硬編碼的方式,可以做為測試使用。同時,spring框架,通過他自己的方式集成上述幾種數據源,理論上來說,都支持。各個數據源連接池都有一些公有的屬性,因為他們都是從javax.sql.datasource繼承而來,而且都有最大連接數,初始化連接數等概念。同時,他們又分別有各自不同的屬性,做了擴展。這里只是簡單的介紹,在實際使用中,想要實現高性能的數據庫連接池管理,還需要深入研究每種方式的連接屬性配置;例如:根據實際需要,設置合適的最小連接數和最大連接數,等待時間等。
注:數據庫連接池要保證連接池的單例