一、問題引入
在java程序中,需要訪問數(shù)據(jù)庫,做增刪改查等相關(guān)操作。如何訪問數(shù)據(jù)庫,做數(shù)據(jù)庫的相關(guān)操作呢?
二、Java連接數(shù)據(jù)庫方法概述
java.sql提供了一些接口和類,用于支持?jǐn)?shù)據(jù)庫增刪改查等相關(guān)的操作。該jar包定義了java訪問各種不同數(shù)據(jù)庫(mysql,oracle,sqlserver。。。。。)的統(tǒng)一接口和標(biāo)準(zhǔn)。同時,各個數(shù)據(jù)庫廠商都提供了該jar包中定義的各個接口的實現(xiàn)類,用于具體實現(xiàn)本廠數(shù)據(jù)庫的增刪改查操作,即稱之為“數(shù)據(jù)庫驅(qū)動jdbc driver”。例如mysql的數(shù)據(jù)庫驅(qū)動為:com.mysql.jdbc.driver;oracle的數(shù)據(jù)庫驅(qū)動為:oracle.jdbc.driver.oracledriver。
在java程序中訪問數(shù)據(jù)庫,做數(shù)據(jù)庫連接時,可以采用兩種方式:
1、使用java.sql API
利用該包提供的各種接口和類直接訪問數(shù)據(jù)庫。
2、使用數(shù)據(jù)庫連接池
目前存在多個開源的java數(shù)據(jù)庫連接池,這些連接池都是在java.sql基礎(chǔ)上編寫而成。
該連接池的解決的問題是:
當(dāng)使用java.sql中提供的api創(chuàng)建數(shù)據(jù)庫連接時候,需要耗費很大的資源,要進(jìn)行用戶名密碼數(shù)據(jù)庫連接驗證等,即耗費資源也耗費時間。如果在程序中,每次需要訪問數(shù)據(jù)庫時候,都進(jìn)行數(shù)據(jù)庫連接,那么勢必會造成性能低下;同時,如果用戶失誤忘記釋放數(shù)據(jù)庫連接,會導(dǎo)致資源的浪費等。而數(shù)據(jù)庫連接池就是解決該問題,通過管理連接池中的多個連接對象(connection),實現(xiàn)connection重復(fù)利用。從而,大大提高了數(shù)據(jù)庫連接方面的性能。
該連接池的功能是:
負(fù)責(zé)創(chuàng)建,管理,釋放,分配數(shù)據(jù)庫連接即(connection)。首先,負(fù)責(zé)創(chuàng)建相應(yīng)數(shù)目的數(shù)據(jù)庫連接對象(connection)對象,并存放到數(shù)據(jù)庫連接池(connect pool)中。當(dāng)用戶請求數(shù)據(jù)庫連接時,該連接池負(fù)責(zé)分配某個處于空閑狀態(tài)的數(shù)據(jù)庫連接對象;當(dāng)用戶發(fā)出釋放該數(shù)據(jù)庫連接時,該連接池負(fù)責(zé)將該連接對象重新設(shè)置為空閑狀態(tài),以便被別的請求重復(fù)利用。同時;數(shù)據(jù)庫連接池負(fù)責(zé)檢查(空閑時間>最大空閑時間)的數(shù)據(jù)庫連接,并釋放。
連接池主要參數(shù)介紹
最小連接數(shù):初始化時,系統(tǒng)將負(fù)責(zé)創(chuàng)建該數(shù)目的connection放入連接池中。
最大連接數(shù):系統(tǒng)允許創(chuàng)建connection的最大數(shù)值。當(dāng)系統(tǒng)請求連接時候,且連接池中不存在空閑的連接:如果connection總數(shù)未超過最大連接數(shù),那么連接池負(fù)責(zé)創(chuàng)建新的connection對象,并返回該對象;如果connection總數(shù)已經(jīng)到達(dá)該最大連接數(shù),那么連接池將用戶請求轉(zhuǎn)入等待隊列。
三、常用的數(shù)據(jù)庫連接池
1、 JNDI
2、 C3p0
3、 Apache 的Jakarta DBCP
4、 BoneCP
其中,sping框架依賴的第三方使用了c3p0和dbcp兩種方式;而bonecp號稱是速度最快的數(shù)據(jù)庫連接池。JNDI方式創(chuàng)建實現(xiàn)的datasource是真正實現(xiàn)了javax.sql.datasource;其他的三種方式都不是。下面的列表,列出了幾種方式的區(qū)別和不同:
序號
連接池名稱
依賴的jar包
實現(xiàn)的datasource類
備注
1
JNDI
該數(shù)據(jù)源是由相應(yīng)的web服務(wù)器(例如:tomcat,weblogic,websphere)負(fù)責(zé)初始化,創(chuàng)建,管理。程序中不需要引入特別的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
備注:以上幾種方式的數(shù)據(jù)庫連接池的配置參數(shù)大同小異,略有差別;其參數(shù)的配置,既可以通過配置文件的方式配置,也可以通過硬編碼的方式配置。
四、分別列出幾種連接池的編碼例子
(所有的例子均可以參考D:\work\qsyworkspace2\jdbctest項目)
1、 使用java.sql API直接訪問數(shù)據(jù)庫
詳細(xì)請參考javasql.java文件。
Class.forName("com.mysql.jdbc.Driver");
String url="jdbc:mysql://localhost:3306/editortest";
String user="root";
String password="123456";
Connection cn=DriverManager.getConnection(url, user, password);
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));
}
2、 使用JNDI方式
這種方式,是由web服務(wù)器,實現(xiàn)了java.sql.datasource。由web服務(wù)器負(fù)責(zé)初始化數(shù)據(jù)源,創(chuàng)建connection,分配,管理connection。由于本身是由web服務(wù)器實現(xiàn)的功能,因此不需要在項目project中引入特別的jar包,但是需要在服務(wù)器的某些配置文件中增加相關(guān)的配置。下面,以tomcat服務(wù)器為例,講述這種方式的使用。
(1)、修改tomcat的conf下的context.xml文件,增加Resource的配置的支持。
(2)、由于數(shù)據(jù)源是由tomcat負(fù)責(zé)創(chuàng)建,所以需要的jdbc驅(qū)動應(yīng)該放到tomcat的lib路徑下。
(3)、編寫使用java代碼,并放在tomcat環(huán)境下使用,如下:
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環(huán)境中測試。因為:java單元的環(huán)境是jdk;而jsp的環(huán)境卻是tomcat;數(shù)據(jù)連接池是在tomcat中配置的,所以能正常運行的,但java測試的環(huán)境只有jdk,所以在引用數(shù)據(jù)連接池時就時出現(xiàn)找不到環(huán)境的錯誤。
使用環(huán)境:當(dāng)使用weblogic或者websphere等高級的web服務(wù)器的時候,可以考慮使用這種方式提高性能。
3、 使用C3p0方式
C3P0是開源的數(shù)據(jù)庫連接組件,支持創(chuàng)建數(shù)據(jù)庫連接池,管理connection等功能。使用該種方式做數(shù)據(jù)庫連接時候,需要導(dǎo)入c3p0-0.9.1.2.jar。
同時,關(guān)于數(shù)據(jù)庫連接的具體參數(shù),例如:url,username,password,最小連接數(shù),最大連接數(shù)。。。。。等信息既可以在xml配置文件中配置,也可以通過程序編碼方式創(chuàng)建。Spring支持c3p0的數(shù)據(jù)庫連接池方式,因此在spring環(huán)境中使用時,支持在applicationcontext.xml文件中配置。另外,由于數(shù)據(jù)庫連接池在整個project中針對某個數(shù)據(jù)庫而言是單例的,所以,即使通過編碼的方式創(chuàng)建,那么要保證其單實例特性。如果存在多個,那么必然會導(dǎo)致性能低下。
下面,列出通過程序編碼方式使用c3p0數(shù)據(jù)庫連接池的方式。
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提供的數(shù)據(jù)源連接池方式,支持?jǐn)?shù)據(jù)庫連接池創(chuàng)建,管理connection等功能。使用環(huán)境,需要導(dǎo)入commons-dbcp.jar 和 commons-pool.jar兩個jar包。上面提到的JNDI方式,其實質(zhì)實用的就是dbcp數(shù)據(jù)源;只是他是通過在web服務(wù)器上做配置,由web服務(wù)器負(fù)責(zé)創(chuàng)建該數(shù)據(jù)源。
同樣的,dbcp數(shù)據(jù)源也支持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是快速高效的數(shù)據(jù)庫連接池組件,據(jù)說性能上目前是最好得,比C3P0和DBCP快25倍。使用該組件,需要導(dǎo)入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();
}
總結(jié):以上,介紹了幾種常用的數(shù)據(jù)源連接池;這幾種連接池在使用過程,即支持硬編碼的方式,也支持配置文件的配置方式;在正式實用的時候,應(yīng)該盡量使用配置的方式,便于維護(hù)和管理。硬編碼的方式,可以做為測試使用。同時,spring框架,通過他自己的方式集成上述幾種數(shù)據(jù)源,理論上來說,都支持。各個數(shù)據(jù)源連接池都有一些公有的屬性,因為他們都是從javax.sql.datasource繼承而來,而且都有最大連接數(shù),初始化連接數(shù)等概念。同時,他們又分別有各自不同的屬性,做了擴(kuò)展。這里只是簡單的介紹,在實際使用中,想要實現(xiàn)高性能的數(shù)據(jù)庫連接池管理,還需要深入研究每種方式的連接屬性配置;例如:根據(jù)實際需要,設(shè)置合適的最小連接數(shù)和最大連接數(shù),等待時間等。
五、Java(x).sql直接操作數(shù)據(jù)庫與各個開源數(shù)據(jù)源(datasource)關(guān)系
當(dāng)使用JDK提供的java(x).sql包中的類訪問數(shù)據(jù)庫時候,基本上用到的就是drivermanager,connection,statement,resultset。其中drivermanger是類,他調(diào)用相應(yīng)的驅(qū)動(即各個數(shù)據(jù)庫廠商提供的驅(qū)動)中的方法生成connection對象。Connection是接口,在各個數(shù)據(jù)庫廠商提供的數(shù)據(jù)庫驅(qū)動中,都實現(xiàn)了該接口。例如:當(dāng)使用com.mysql.jdbc.driver時候,生成的connection即為com.mysql.jdbc.Connection對象。
Javax.sql包中定義了接口datasource,統(tǒng)一規(guī)定了作為數(shù)據(jù)源連接池必須提供的方法和屬性等。各個數(shù)據(jù)源組件中提供的datasource都實現(xiàn)了該接口。當(dāng)通過數(shù)據(jù)源連接池的方式獲取connnection的時候,同樣的,各個數(shù)據(jù)源組件也都提供(實現(xiàn)了java.sql.connection)接口的類。
更為具體的細(xì)節(jié),可以參考jdk文檔中關(guān)于java(x).sql包中相關(guān)類和接口的描述;參考開源數(shù)據(jù)源連接池組件的相關(guān)源碼(例如C3P0);參考相關(guān)的數(shù)據(jù)庫驅(qū)動。
六、附錄:Java開源的數(shù)據(jù)庫連接池
在Java中開源的數(shù)據(jù)庫連接池有以下幾種 :
1, C3P0 C3P0是一個開放源代碼的JDBC連接池,它在lib目錄中與Hibernate一起發(fā)布,包括了實現(xiàn)jdbc3和jdbc2擴(kuò)展規(guī)范說明的Connection 和Statement 池的DataSources 對象。
2,Proxool 這是一個Java SQL Driver驅(qū)動程序,提供了對你選擇的其它類型的驅(qū)動程序的連接池封裝??梢苑浅:唵蔚囊浦驳浆F(xiàn)存的代碼中。完全可配置??焖?,成熟,健壯??梢酝该鞯貫槟悻F(xiàn)存的JDBC驅(qū)動程序增加連接池功能。
3,Jakarta DBCP DBCP是一個依賴Jakarta commons-pool對象池機(jī)制的數(shù)據(jù)庫連接池.DBCP可以直接的在應(yīng)用程序用使用。
4,DDConnectionBroker DDConnectionBroker是一個簡單,輕量級的數(shù)據(jù)庫連接池。
5,DBPool DBPool是一個高效的易配置的數(shù)據(jù)庫連接池。它除了支持連接池應(yīng)有的功能之外,還包括了一個對象池使你能夠開發(fā)一個滿足自已需求的數(shù)據(jù)庫連接池。
6,XAPool XAPool是一個XA數(shù)據(jù)庫連接池。它實現(xiàn)了javax.sql.XADataSource并提供了連接池工具。
7,Primrose Primrose是一個Java開發(fā)的數(shù)據(jù)庫連接池。當(dāng)前支持的容器包括Tomcat4&5,Resin3與JBoss3.它同樣也有一個獨立的版本可以在應(yīng)用程序中使用而不必運行在容器中。Primrose通過一個web接口來控制SQL處理的追蹤,配置,動態(tài)池管理。在重負(fù)荷的情況下可進(jìn)行連接請求隊列處理。
8,SmartPool SmartPool是一個連接池組件,它模仿應(yīng)用服務(wù)器對象池的特性。SmartPool能夠解決一些臨界問題如連接泄漏(connection leaks),連接阻塞,打開的JDBC對象如Statements,PreparedStatements等. SmartPool的特性包括支持多個pools,自動關(guān)閉相關(guān)聯(lián)的JDBC對象, 在所設(shè)定time-outs之后察覺連接泄漏,追蹤連接使用情況, 強(qiáng)制啟用最近最少用到的連接,把SmartPool"包裝"成現(xiàn)存的一個pool等。
9,MiniConnectionPoolManager MiniConnectionPoolManager是一個輕量級JDBC數(shù)據(jù)庫連接池。它只需要Java1.5(或更高)并且沒有依賴第三方包。
10,BoneCP BoneCP是一個快速,開源的數(shù)據(jù)庫連接池。幫你管理數(shù)據(jù)連接讓你的應(yīng)用程序能更快速地訪問數(shù)據(jù)庫。比C3P0/DBCP連接池快25倍。
聯(lián)系客服