Tomcat 內建 DBCP (Database Connection Pool) 提供高效能資料庫連線池管理。本文以 Tomcat 5.0 + Informix 為例,詳細說明單一與多 JNDI 資料源配置步驟、web.xml 宣告、驅動程式部署與 Java 程式碼存取方式。
com.informix.jdbc.IfxDriver)$CATALINA_HOME/lib (Tomcat 6+) 或 $CATALINA_HOME/common/lib (Tomcat 5)<DefaultContext>
<Resource name="jdbc/testdb0_cs" auth="Container" type="javax.sql.DataSource"/>
<ResourceParams name="jdbc/testdb0_cs">
<parameter>
<name>factory</name>
<value>org.apache.commons.dbcp.BasicDataSourceFactory</value>
</parameter>
<parameter>
<name>driverClassName</name>
<value>com.informix.jdbc.IfxDriver</value>
</parameter>
<parameter>
<name>url</name>
<value>jdbc:informix-sqli://192.177.191.130:6666/testdb0_cs:INFORMIXSERVER=ccbhr_test</value>
</parameter>
<parameter><name>username</name><value>hrmis</value></parameter>
<parameter><name>password</name><value>hrmis</value></parameter>
<parameter><name>maxActive</name><value>20</value></parameter>
<parameter><name>maxIdle</name><value>10</value></parameter>
<parameter><name>poolPrepareStatements</name><value>true</value></parameter>
<parameter><name>removeAbandoned</name><value>true</value></parameter>
<parameter><name>removeAbandonedTimeout</name><value>60</value></parameter>
<parameter><name>logAbandoned</name><value>false</value></parameter>
</ResourceParams>
</DefaultContext>
<resource-ref>
<description>連線測試資料庫</description>
<res-ref-name>jdbc/testdb0_cs</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
<DefaultContext>
<!-- 第一個資料源 -->
<Resource name="jdbc/testdb0_cs1" auth="Container" type="javax.sql.DataSource"/>
<ResourceParams name="jdbc/testdb0_cs1">
<parameter><name>factory</name><value>org.apache.commons.dbcp.BasicDataSourceFactory</value></parameter>
<parameter><name>driverClassName</name><value>com.informix.jdbc.IfxDriver</value></parameter>
<parameter><name>url</name><value>jdbc:informix-sqli://192.177.179.208:6666/testdb0_cs1:INFORMIXSERVER=ccbhr_test</value></parameter>
<parameter><name>username</name><value>informix</value></parameter>
<parameter><name>password</name><value>google</value></parameter>
<!-- 連線池參數同單一資料源 -->
</ResourceParams>
<!-- 第二個資料源 -->
<Resource name="jdbc/testdb0_cs" auth="Container" type="javax.sql.DataSource"/>
<ResourceParams name="jdbc/testdb0_cs">
<parameter><name>factory</name><value>org.apache.commons.dbcp.BasicDataSourceFactory</value></parameter>
<parameter><name>driverClassName</name><value>com.informix.jdbc.IfxDriver</value></parameter>
<parameter><name>url</name><value>jdbc:informix-sqli://192.177.191.130:6666/testdb0_cs:INFORMIXSERVER=ccbhr_test</value></parameter>
<parameter><name>username</name><value>informix</value></parameter>
<parameter><name>password</name><value>informix</value></parameter>
<!-- 連線池參數同單一資料源 -->
</ResourceParams>
</DefaultContext>
<resource-ref>
<description>資料庫 1</description>
<res-ref-name>jdbc/testdb0_cs</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
<resource-ref>
<description>資料庫 2</description>
<res-ref-name>jdbc/testdb0_cs1</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
| 參數 | 說明 | 建議值 |
|---|---|---|
| maxActive | 最大活躍連線數 (0=無限制) | 20-100 視負載 |
| maxIdle | 最大閒置連線數 | maxActive 的 30-50% |
| maxWait | 取得連線最長等待毫秒數 (-1=無限等待) | 10000 (10秒) |
| removeAbandoned | 是否回收被遺棄連線 | true |
| removeAbandonedTimeout | 判定遺棄的閒置秒數 | 60-300 |
| logAbandoned | 記錄遺棄連線堆疊追蹤 | 開發 true / 生產 false |
| poolPrepareStatements | 緩存 PreparedStatement | true (提升效能) |
| validationQuery | 連線驗證 SQL (如 SELECT 1) | 視資料庫而定 |
| testOnBorrow | 借用時驗證 | true |
| testWhileIdle | 閒置驗證 | true |
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.sql.DataSource;
import java.sql.Connection;
public class DataSourceUtil {
public static Connection getConnection(String dsnName) {
try {
String jndiName = "java:comp/env/jdbc/" + dsnName.trim();
Context ctx = new InitialContext();
DataSource ds = (DataSource) ctx.lookup(jndiName);
return ds.getConnection();
} catch (Exception e) {
throw new RuntimeException("取得資料源 [" + dsnName + "] 失敗: " + e.getMessage(), e);
}
}
}
// 使用範例
Connection conn1 = DataSourceUtil.getConnection("testdb0_cs");
Connection conn2 = DataSourceUtil.getConnection("testdb0_cs1");
新版 Tomcat 建議使用 META-INF/context.xml 或 $CATALINA_HOME/conf/context.xml:
<Context>
<Resource name="jdbc/myapp"
auth="Container"
type="javax.sql.DataSource"
factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
driverClassName="com.mysql.cj.jdbc.Driver"
url="jdbc:mysql://localhost:3306/myapp?useSSL=false&serverTimezone=UTC"
username="root"
password="secret"
maxActive="50"
maxIdle="20"
minIdle="5"
maxWait="10000"
removeAbandonedTimeout="60"
removeAbandoned="true"
logAbandoned="false"
testOnBorrow="true"
validationQuery="SELECT 1"
testWhileIdle="true"
timeBetweenEvictionRunsMillis="30000"/>
</Context>
注意:Tomcat 7+ 預設使用 org.apache.tomcat.jdbc.pool.DataSourceFactory (Tomcat JDBC Pool),效能優於舊版 Commons DBCP。
$CATALINA_HOME/libjava:comp/env/jdbc/ 前綴與 resource-ref 名稱一致removeAbandoned=true 並檢查代碼確保 finally 區塊關閉連線autoReconnect=true 或配置 validationQuery 定期驗證