環境:1. 資料庫:Microsoft SQL Server 2000
2. 資料庫驅動程式:net.sourceforge.jtds.jdbc.Driver
JNDI(Java Naming and Directory Interface)概述:
Tomcat4(5)提供了一個與Java Enterprise Edition應用服務相相容的JNDI--InitialContext實現執行個體。它的初始資料設定在$CATALINA_HOME/conf/server.xml檔案裡,並可能在網頁應用環境描述(/WEB-INF/web.xml)裡被下列元素引用:
1) <env-entry>--環境入口,設定應用程式如何操作。
2) <resource-ref>--資源參數,一般是資料庫驅動程式、JavaMail Session、自訂類工廠等。
3) <resource-env-ref>--在Servlet 2.4裡用來簡化設定不需認證資訊的資源資源如環境參數、resource-ref變數。
InitialContext在網頁應用程式初始化時被設定,用來支援網頁應用程式組件。所有的入口和資源都放在JNDI命名空間裡的java:comp/env段裡。點擊下列網址以擷取更多資訊:
1) Java命名和目錄介面(Java Naming and Directory Interface)
2) J2EE平台說明(J2EE Platform Specification)
設定JNDI資源
設定JNDI資源要在$CATALINA_HOME/conf/server.xml檔案裡使用下列標誌符:
1) <Environment>--設定域個可變的JNDI InitialContext入口的名字和值(同上面說的<env-entry>等價)。
2) <Resource>--設定應用程式可用的資源的名字和類型(同上面說的<resource-ref>等價)。
3) <ResourceParams>--設定Java資源類工廠的名稱或將用的JavaBean屬性。
4) <ResourceLink>--給全域JNDI環境(JNDI Context)添加一個連結。
上述這些標誌符必須放在<Context>和</Context>之間(針對專門的網頁應用程式)或<DefaultContext>和</DefaultContext>之間。
此外,設在網頁應用環境描述(Web Application Descriptor)(/WEB-INF/web.xml)裡的名字和值也在初始環境(Initial Context)裡被設定,當被<Environemt>元素值允許時將被重設初始值。
全域變數能在<Server>子項目的<GlobalNamingResources>裡設定。
資料庫連接池概述:
資料庫連接是一種關鍵的有限的昂貴的資源,這一點在多使用者的網頁應用程式中體現得尤為突出。對資料庫連接的管理能顯著影響到整個應用程式的伸縮性和健壯性,影響到程式的效能指標。資料庫連接池正是針對這個問題提出來的。
資料庫連接池負責分配、管理和釋放資料庫連接,它允許應用程式重複使用一個現有的資料庫連接,而再不是重建立立一個;釋放空閑時間超過最大空閑時間的資料庫連接來避免因為沒有釋放資料庫連接而引起的資料庫連接遺漏。這項技術能明顯提高對資料庫操作的效能。
資料庫連接池在初始化時將建立一定數量的資料庫連接放到串連池中,這些資料庫連接的數量是由最小資料庫連接數來設定的。無論這些資料庫連接是否被使用,串連池都將一直保證至少擁有這麼多的串連數量。串連池的最大資料庫連接數量限定了這個串連池能佔有的最大串連數,當應用程式向串連池請求的串連數超過最大串連數量時,這些請求將被加入到等待隊列中。資料庫連接池的最小串連數和最大串連數的設定要考慮到下列幾個因素:
1) 最小串連數是串連池一直保持的資料庫連接,所以如果應用程式對資料庫連接的使用量不大,將會有大量的資料庫連接資源被浪費;
2) 最大串連數是串連池能申請的最大串連數,如果資料庫連接請求超過此數,後面的資料庫連接請求將被加入到等待隊列中,這會影響之後的資料庫操作。
3) 如果最小串連數與最大串連數相差太大,那麼最先的串連請求將會獲利,之後超過最小串連數量的串連請求等價於建立一個新的資料庫連接。不過,這些大於最小串連數的資料庫連接在使用完不會馬上被釋放,它將被放到串連池中等待重複使用或是空閑逾時後被釋放。
配置Tomcat資料庫連接池的前提:
1. 必須裝有Java運行環境;
2. 必須有SQL Server2000資料庫伺服器(可以不在本地);
3. 必須有jtds.jar,並將它放在$CATALINA_HOME/common/lib目錄下(只能是這裡)。使用它是因為Microsoft公司的Java SQL Server驅動程式不支援二次查詢,可到網上搜到。目前使用的是jtds-0.6.jar。
在$CATALINA_HOME/conf/server.xml裡設定資料庫連接池:
下面是配置的代碼,必須放在<Host>和</Host>之間。
<Context path="/quality" docBase="quality" debug="0" reloadable="true" crossContext="true">
<Logger className="org.apache.catalina.logger.FileLogger" prefix="localhost_quality_log." suffix=".txt" timestamp="true"/>
<Resource name="jdbc/connectDB" auth="Container" type="javax.sql.DataSource"/>
<ResourceParams name="jdbc/connectDB">
<parameter>
<name>maxActive</name>
<!-- Maximum number of DB connections in pool.Set to 0 for no limit. -->
<value>100</value>
</parameter>
<parameter>
<name>maxIdle</name>
<!-- Maximum number of idle DB connections to retain in pool.Set to 0 for no limit. -->
<value>30</value>
</parameter>
<parameter>
<name>maxWait</name>
<!-- Maximum time to wait for a DB connection to become available in ms.An exception is thrown if this timeout is exceeded.Set to -1 to wait indefinitely. -->
<value>10000</value>
</parameter>
<parameter>
<name>removeAbandoned</name>
<!-- Abandoned DB connections are removed and recycled -->
<value>true</value>
</parameter>
<parameter>
<name>removeAbandonedTimeout</name>
<!-- Use the removeAbandonedTimeout parameter to set the number of seconds a DB connection has been idle before it is considered abandoned. -->
<value>60</value>
</parameter>
<parameter>
<name>logAbandoned</name>
<!-- Log a stack trace of the code which abandoned -->
<value>false</value>
</parameter>
<parameter>
<name>factory</name>
<!-DBCP Basic Datasource Factory -->
<value>org.apache.commons.dbcp.BasicDataSourceFactory</value>
</parameter>
<parameter>
<name>username</name>
<!-- Database User Name -->
<value>Iorishinier</value>
</parameter>
<parameter>
<name>password</name>
<!-- User Password -->
<value>mypasswd</value>
</parameter>
<parameter>
<name>driverClassName</name>
<!-- Database Driver Class Name -->
<value>net.sourceforge.jtds.jdbc.Driver</value>
</parameter>
<parameter>
<name>url</name>
<!-- Database Address -->
<value>jdbc:jtds:sqlserver://127.127.127.127:1433/Northwind</value>
</parameter>
</ResourceParams>
</Context> |
下面是一些參數的說明:
<Context path="/quality" docBase="quality" debug="0" reloadable="true" crossContext="true">
其中:
1) path 指定路徑,這裡設定的是$CATALINA_HOME/webapps下的quality目錄;
2) docBase 檔案根目錄。
3) reloader 當網頁被更新時是否重新編譯。
4) maxActive 串連池的最大資料庫連接數。設為0表示無限制。
5) maxIdle 資料庫連接的最大空閑時間。超過此空閑時間,資料庫連接將被標記為不可用,然後被釋放。設為0表示無限制。
6) maxWait 最大建立串連等待時間。如果超過此時間將接到異常。設為-1表示無限制。
7) removeAbandoned 回收被遺棄的(一般是忘了釋放的)資料庫連接到串連池中。
8) removeAbandonedTimeout 資料庫連接過多長時間不用將被視為被遺棄而收回串連池中。
9) logAbandoned 將被遺棄的資料庫連接的回收記入日誌。
10) driverClassName JDBC驅動程式。
11) url 資料庫連接字串
在$CATALINA_HOME/webapps/quality/WEB-INF/web.xml裡設定被引用的資源:
下面是配置代碼,必須放在<web-app>和</web-app>裡。
<!-- Database Config start -->
<resource-ref>
<description>connectDB test</description>
<res-ref-name>jdbc/connectDB</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
<!-- Database Config end -->
下面是一下參數的必要說明:
1) description 對被引用的資源的描述。
2) res-ref-name 資源名稱。見上面的<ResourceParams name="jdbc/connectDB">
3) res-type 資源類型。見上面的<Resource name="jdbc/connectDB" auth="Container" type="javax.sql.DataSource"/>
在JSP中使用資源:
這是在$CATALINA_HOME/webapps/quality下的某級子目錄裡的jsp網頁檔案部分代碼:
<%@ page contentType="text/html;charset=GBK"%>
<%@ page errorPage="error.jsp"%>
<%@ page import="javax.naming.*"%>
<%@ page import="javax.sql.*"%>
<%@ page import="java.sql.*"%>
<html>
<head>
</head>
<body>
<%
………………
………………
// 資料庫操作
Context ctx=null;
Connection cnn=null;
Statement stmt=null;
ResultSet rs=null;
try
{
ctx=new InitialContext();
if(ctx==null)
throw new Exception("沒有匹配的環境");
DataSource ds=(DataSource)ctx.lookup("java:comp/env/jdbc/connectDB");
if(ds==null)
throw new Exception("沒有匹配資料庫");
cnn=ds.getConnection();
stmt=cnn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_READ_ONLY);
rs=stmt.executeQuery("select * from table1");
………………
………………
}
finally
{
if(rs!=null)
rs.close();
if(stmt!=null)
stmt.close();
if(cnn!=null)
cnn.close();
if(ctx!=null)
ctx.close();
}
%>
</body>
</html> |
代碼說明:
DataSource ds=(DataSource)ctx.lookup("java:comp/env/jdbc/connectDB");
上面這句應用了剛才設的資源。
資源使用完要釋放,尤其是Context資源,見try-catch-finally部分的finally程式碼片段,這是一種好的習慣。資源釋放時如果釋放了上級資源,下級資源將先被釋放。如:釋放了ctx,那麼資源釋放順序將是rs,stmt,cnn,ctx。換句話說,如果釋放了ctx,那麼rs,stmt和cnn都將不可用了。
這裡的釋放資源只是將資料庫連接返回串連池中,並不是把資源真正釋放掉,見資料庫連接池概述。
By Iorishinier(原作)