| 維度 | 全域共享 (conf/context.xml) | 專案獨立 (META-INF/context.xml) |
|---|---|---|
| 適用場景 | 多專案共用同一資料庫、統一維運 | 專案獨立資料庫、隔離配置、避免衝突 |
| 配置檔位置 | $CATALINA_BASE/conf/context.xml | WebApp/META-INF/context.xml |
| 生效範圍 | Tomcat 所有 Web 應用 | 僅當前 Web 應用 |
| 修改生效 | 需重啟 Tomcat | 熱部署/重新部署即可 |
conf/context.xml (在 <Context> 內)<Resource
name="jdbc/myDataSource"
auth="Container"
type="javax.sql.DataSource"
driverClassName="com.microsoft.sqlserver.jdbc.SQLServerDriver"
url="jdbc:sqlserver://127.0.0.1\:1433;DatabaseName=ShopSystem"
username="sa"
password="xx"
maxActive="20"
maxIdle="10"
maxWait="5000"
validationQuery="SELECT 1"
testOnBorrow="true"
testWhileIdle="true"
timeBetweenEvictionRunsMillis="30000"
minEvictableIdleTimeMillis="60000"
removeAbandonedOnBorrow="true"
removeAbandonedTimeout="60"
logAbandoned="true"
/>
關鍵屬性說明:
maxActive:最大活躍連線數 (0=無限)。maxIdle:池中保留最大閒置連線。maxWait:取得連線最長等待毫秒數。validationQuery + testOnBorrow:借用前驗證連線有效,防斷連。removeAbandonedOnBorrow:自動回收泄漏連線 (超過 removeAbandonedTimeout 秒未歸還)。conf/web.xml 或專案 WEB-INF/web.xml 宣告資源參考<resource-ref>
<res-ref-name>jdbc/myDataSource</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
WebApp/META-INF/context.xml<?xml version="1.0" encoding="UTF-8"?>
<Context>
<Resource
name="jdbc/myDS"
auth="Container"
type="javax.sql.DataSource"
driverClassName="com.microsoft.sqlserver.jdbc.SQLServerDriver"
url="jdbc:sqlserver://127.0.0.1\:1433;DatabaseName=ShopSystem"
username="sa"
password="xx"
maxActive="10"
maxIdle="5"
maxWait="3000"
validationQuery="SELECT 1"
testOnBorrow="true"
/>
</Context>
WEB-INF/web.xml 宣告<resource-ref>
<res-ref-name>jdbc/myDS</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
tomcat/lib/無論哪種策略,資料庫驅動 JAR (如 sqljdbc4.jar, mysql-connector-java.jar, ojdbc8.jar) 必須放在 $CATALINA_BASE/lib/,否則類別載入失敗 (ClassNotFoundException)。
<%@ page import="javax.naming.*, javax.sql.*, java.sql.*" %>
<%
Context initCtx = new InitialContext();
Context envCtx = (Context) initCtx.lookup("java:comp/env");
DataSource ds = (DataSource) envCtx.lookup("jdbc/myDataSource"); // 或 jdbc/myDS
try (Connection conn = ds.getConnection();
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT a_name FROM admin")) {
while (rs.next()) {
out.print(rs.getString("a_name") + "<br/>");
}
}
%>
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:comp/env/jdbc/myDataSource"/>
<property name="resourceRef" value="true"/>
</bean>
或使用 <jee:jndi-lookup> 命名空間簡化。
NameNotFoundException: Name [jdbc/myDataSource] is not boundcontext.xml 的 name 與 web.xml res-ref-name 完全一致。java:comp/env/jdbc/xxx (不可省略前綴)。META-INF/context.xml 是否隨 WAR 部署 (部分 IDE 需配置資源複製)。Communications link failurevalidationQuery + testOnBorrow="true" (或 testWhileIdle + evictor 執行緒)。MySQL 8.0+ 建議 validationQuery="SELECT 1"。com.microsoft.sqlserver.jdbc.SQLServerDriver;mssql-jdbc 9.0+ 同類別名,確認 JAR 版本對應 JDK 版本。conf/Catalina/localhost/專案名.xml,刪除該檔案並重新部署,或重啟 Tomcat。maxActive 依據資料庫最大連線數與應用並發度設定 (通常 20~100)。testWhileIdle + timeBetweenEvictionRunsMillis 定期清理斷連。numActive/numIdle (JMX 或 /manager/status) 動態調整。