Tomcat 6+ 自動掃描專案 WebRoot/META-INF/context.xml(或 src/main/webapp/META-INF/context.xml),無需在 web.xml 額外設定。
<?xml version="1.0" encoding="UTF-8"?>
<Context reloadable="true" crossContext="true">
<Resource name="jdbc/test"
auth="Container"
type="javax.sql.DataSource"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/haotian?autoReconnect=true&useUnicode=true&characterEncoding=UTF-8"
username="root"
password="root"
maxActive="20"
maxIdle="10"
maxWait="-1"
validationQuery="SELECT 1"
testOnBorrow="true"
removeAbandoned="true"
removeAbandonedTimeout="60"
logAbandoned="true" />
</Context>
關鍵屬性:
validationQuery + testOnBorrow:借用連線前自動驗證,防止 MySQL 8 小時斷連導致的 Communications link failure。removeAbandoned:自動回收未正確關閉的連線,避免洩漏耗盡連線池。public class DBConnection {
public Connection getConnection() throws NamingException, SQLException {
Context initCtx = new InitialContext();
Context envCtx = (Context) initCtx.lookup("java:comp/env");
DataSource ds = (DataSource) envCtx.lookup("jdbc/test"); // 對應 Resource name
return ds.getConnection();
}
}
建議搭配 try-with-resources 自動關閉:
try (Connection conn = new DBConnection().getConnection();
PreparedStatement ps = conn.prepareStatement(sql);
ResultSet rs = ps.executeQuery()) {
// 業務邏輯
}
必須將 MySQL Connector/J (mysql-connector-java-x.x.x.jar) 放入 Tomcat 的 lib/ 目錄,而非專案 WEB-INF/lib/。原因:
ClassNotFoundException: com.mysql.jdbc.Driver。不可在 main() 方法直接測試**,因無 JNDI 環境會拋出 NoInitialContextException。正確做法:
DBConnection 的 Servlet/JSP。show processlist)。| 現象 | 原因 | 解決 |
|---|---|---|
| Communications link failure | MySQL wait_timeout 過短 | 加 validationQuery + testOnBorrow |
| Connection leak | 未在 finally 關閉連線 | try-with-resources / removeAbandoned |
| ClassNotFoundException | 驅動包放錯位置 | 移至 $CATALINA_HOME/lib |