DBCP能夠集中管理Web應用中的所有連接,提前創建好若幹到數據庫的連接,用戶需要的時候從連接池中獲取壹個連接,用完之後重新把連接放回連接池。要使用DBCP,首先需要配置JNDI數據源。
配置JNDI數據源
DBCP可以使用很多技術實現,本書介紹的是比較流行的Jakarta-Commons的DBCP。
使用連接池的時候,存在壹個問題。Web應用必須顯式的關閉結果集對象、語句對象、連接對象,如果關閉失敗,將導致這些對象不能重用。可能還會導致在連接使用完的時候,Web應用無法連接到數據庫。
Jakarta-Commons的DBCP提供了壹種機制,能夠跟蹤和恢復那些不能被管理的連接。要想跟蹤和恢復那些不能被管理的連接,需要在配置數據源的時候增加下面的代碼:
removeAbandoned="true"
當可用的連接數比較少的使用,連接池會查找並重復使用這些不能被管理的連接。可以使用removeAbandonedTimeout屬性設置壹個連接空閑多少秒之後被認為是已經被放棄的,默認值是300秒。如果想改為60秒,可以使用下面的代碼:
removeAbandonedTimeout="60"
可以設置logAbandoned屬性來記錄沒有正確釋放連接的代碼:
logAbandoned="true"
<!--局部數據庫連接池(兩種方法) Tomcat6.0連接池配置 -->
<!--第壹種方法-->
配置server.xml
server.xml文件在Tomcat安裝目錄的conf子目錄下。在</host>之前增加下面的代碼:
<Context path="/bookstore" docBase="bookstore(項目名稱)"
debug="5" reloadable="true" crossContext="true">
<Resource name="jdbc/connpool" auth="Container" type="javax.sql.DataSource"
maxActive="100" maxIdle="30" maxWait="10000"
username="j2ee"
password="j2ee"
driverClassName="oracle.jdbc.driver.OracleDriver"
url="jdbc:oracle:thin:@127.0.0.1:1521:orcl"/>
</Context>
<!--第二種方法-->
<Resource name="jdbc/connpool" auth="Container" type="javax.sql.DataSource" maxActive="100" maxIdle="30"
maxWait="10000" username="j2ee" password="j2ee" driverClassName="oracle.jdbc.driver.OracleDriver"
url="jdbc:oracle:thin:@127.0.0.1:1521:orcl"/>
各屬性的含義如下:
1 maxActive: 池中連接的最大數目。要確保把mysql的最大連接數大於這個值。如果為0,則沒有最大數量限制。
2 maxIdle: 池中最大空閑數據庫連接數。如果為-1,則沒有限制。
3 axWait: 等待壹個連接變成可用的最長時間,單位是ms,這個例子中是10秒,如果超時將拋出異常。如果設置為-1,將無限等待
4 username 和 password: 連接MySQL數據庫的用戶名和口令
5 driverClassName: MySQL數據庫的JDBC驅動程序的名字,這裏驅動的名字是com.mysql.jdbc.Driver。
6 url: JDBC連接MySQL數據庫的url。參數autoReconnect=true確保連接池能夠重新連接,如果8個小時沒有操作,mysql管理器會關閉連接。
配置web.xml
需要為當前應用配置web.xml。主要作用是聲明數據源。代碼如下:
<web-app xmlns="/xml/ns/j2ee"
xmlns:xsi="/xml/ns/j2ee version="2.4">
<description>MySQL Test App</description>
<resource-ref>
<description>DB Connection</description>
<res-ref-name>jdbc/TestDB</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
</web-app>
使用連接池訪問數據庫
使用連接池訪問數據庫與使用JDBC直接訪問數據庫的過程基本相同,只是得到連接的方式不同。
下面的代碼展示了在使用連接池的時候,如果獲取到數據庫的連接。
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
public class DBPool {
private static DataSource pool;
static {
Context env = null;
try {
env = (Context) new InitialContext().lookup("java:comp/env");
pool = (DataSource)env.lookup("jdbc/DBPool");
if(pool==null)
System.err.println("'DBPool' is an unknown DataSource");
} catch(NamingException ne) {
ne.printStackTrace();
}
}
public static DataSource getPool() {
return pool;
}
}
全局數據庫連接池的配置:
1.將數據庫驅動程序的JAR文件放在Tomcat的 common/lib 中;
2.在server.xml中設置數據源,以Oracle數據庫為例,如下:
在<GlobalNamingResources> </GlobalNamingResources>節點中加入,
<Resource
name="jdbc/connpool"
type="javax.sql.DataSource"
password="j2ee"
driverClassName="oracle.jdbc.driver.OracleDriver"
maxIdle="2"
maxWait="5000"
username="j2ee"
url="jdbc:oracle:thin:@127.0.0.1:1521:orcl"
maxActive="4"/>
屬性說明:name,數據源名稱,通常取”jdbc/XXX”的格式;
type,”javax.sql.DataSource”;
password,數據庫用戶密碼;
driveClassName,數據庫驅動;
maxIdle,最大空閑數,數據庫連接的最大空閑時間。超過空閑時間,數據庫連
接將被標記為不可用,然後被釋放。設為0表示無限制。
MaxActive,連接池的最大數據庫連接數。設為0表示無限制。
maxWait ,最大建立連接等待時間。如果超過此時間將接到異常。設為-1表示
無限制。
3.在妳的web應用程序的web.xml中設置數據源參考,如下:
在<web-app></web-app>節點中加入,
<resource-ref>
<description>MySQL DB Connection Pool</description>
<res-ref-name>jdbc/connpool</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
<res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>
子節點說明: description,描述信息;
res-ref-name,參考數據源名字,同上壹步的屬性name;
res-type,資源類型,”javax.sql.DataSource”;
res-auth,”Container”;
res-sharing-scope,”Shareable”;
<!--以下為設置數據源連接-->
<!--第壹種-->
在tomcat\webapps\myapp\META-INF\context.xml的Context中增加:
<ResourceLink name="jdbc/connPool" global="jdbc/connPool" type="javax.sql.DataSource"/>
這樣就可以了。
<!--第二種-->
在web應用程序的context.xml中設置數據源鏈接,如下:
在<Context></Context>節點中加入,
<ResourceLink
name="jdbc/connpool"
type="javax.sql.DataSource"
global="jdbc/connpool"/>
屬性說明:name,同第2步和第3步的屬性name值,和子節點res-ref-name值;
type,同樣取”javax.sql.DataSource”;
global,同name值。
至此,設置完成,下面是如何使用數據庫連接池。
1.建立壹個連接池類,DBPool.java,用來創建連接池,代碼如下:
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
public class DBPool {
private static DataSource pool;
static {
Context env = null;
try {
env = (Context) new InitialContext().lookup("java:comp/env");
pool = (DataSource)env.lookup("jdbc/DBPool");
if(pool==null)
System.err.println("'DBPool' is an unknown DataSource");
} catch(NamingException ne) {
ne.printStackTrace();
}
}
public static DataSource getPool() {
return pool;
}
}
2.在要用到數據庫操作的類或jsp頁面中,用DBPool.getPool().getConnection(),獲得壹個Connection對象,就可以進行數據庫操作,最後別忘了對Connection對象調用close()方法,註意:這裏不會關閉這個Connection,而是將這個Connection放回數據庫連接池。
第三種:tomcat5.0連接池配置
1.打開server.xml:在<Context > </Contex>中添加如下連接池參數語句,壹個完整的例子如下:
<?xml version='1.0' encoding='utf-8'?>
<Context docBase="E:\Projects\ColorRing\wap" path="/wap" reloadable="true">
<Resource name="jdbc/wapOracle" auth="Container"
type="javax.sql.DataSource"/>
<ResourceParams name="jdbc/wapOracle"> <!--這裏name的值必須與Resource裏的name的值相同-->
<parameter>
<name>factory</name>
<value>org.apache.commons.dbcp.BasicDataSourceFactory</value>
</parameter>
<parameter>
<name>url</name>
<value>jdbc:oracle:thin:@172.18.51.101:1521:sundb</value> <!--連接數據庫的url-->
</parameter>
<parameter>
<name>maxIdle</name>
<value>20</value>
</parameter>
<parameter>
<name>maxActive</name>
<value>0</value>
</parameter>
<parameter>
<name>driverClassName</name>
<value>oracle.jdbc.driver.OracleDriver</value>
</parameter>
<parameter>
<name>maxWait</name>
<value>5000</value>
</parameter>
<parameter>
<name>removeAbandoned</name>
<value>true</value>
</parameter>
<parameter>
<name>username</name> <!--用戶名-->
<value>cms_user</value>
</parameter>
<parameter>
<name>logAbandoned</name>
<value>true</value>
</parameter>
<parameter>
<name>removeAbandonedTimeout</name>
<value>60</value>
</parameter>
<parameter>
<name>password</name> <!--密碼-->
<value>12345</value>
</parameter>
</ResourceParams>
</Context>
2.打開工程下的WEB-INF/web.xml,添加如下部分:
<resource-ref>
<description>Oracle Datasource example</description>
<res-ref-name>jdbc/wapOracle</res-ref-name> <!--這裏name的值也必須與server.xml中的Resource裏的
name的值相同-->
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
3.然後寫連接數據庫的語句:
package util;
import java.sql.*;
import javax.sql.*;
import javax.naming.*;
public class OracleDB {
String url_ = "192.168.1.41:1521:gxcring";
//String url_ = "172.18.51.101:1521:SUNDB";
String id_ = "cms_user";
String pass_ = "12345";
Connection conn = null;
Statement stmt = null;
public OracleDB() {
try {
//Class.forName("oracle.jdbc.driver.OracleDriver");
//conn = DriverManager.getConnection("jdbc:oracle:thin:@" + url_, id_, pass_);
Context initContext = new InitialContext();
Context envContext = (Context) initContext.lookup("java:/comp/env");
DataSource ds = (DataSource) envContext.lookup("jdbc/wapOracle"); //註意這裏的名字與配置文件
裏的名字相同就行了。
conn = ds.getConnection();
stmt = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_UPDATABLE);
} catch (NamingException ne) {
System.out.println("Initial DataSource error.");
ne.printStackTrace();
} catch (SQLException e) {
System.out.println("ORACLE: " + e);
e.printStackTrace();
}
}
/**
* 返回Connction對象
* @param none
* @return Connction
*/
public Connection getConn() {
return this.conn;
}
}