首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 程式設計入門

Java 資料庫連線池配置實戰:Tomcat JNDI 整合與 Spring 管理全流程

     編輯:Java 程式設計入門

為什麼需要連線池?

傳統 JDBC 每次請求都經歷「載入驅動 → 建立連線 → 執行 SQL → 關閉連線」,連線建立/銷毀開銷極大,高併發下極易耗盡資料庫連線資源導致系統癱瘓。連線池核心思想:啟動時預建連線物件池,請求時借用、用畢歸還,實現複用。

核心參數解析

方案一:Tomcat 原生 JNDI 資料源(web.xml + context.xml)

步驟 1:context.xml 定義 Resource

<Context>
  <Resource name="jdbc/news"
            auth="Container"
            type="javax.sql.DataSource"
            maxTotal="100"
            maxIdle="30"
            maxWaitMillis="10000"
            username="sa"
            password="120010"
            driverClassName="com.microsoft.sqlserver.jdbc.SQLServerDriver"
            url="jdbc:sqlserver://localhost:1433;DatabaseName=news"
            validationQuery="SELECT 1"
            testOnBorrow="true"
            testWhileIdle="true"
            timeBetweenEvictionRunsMillis="30000"
            minEvictableIdleTimeMillis="60000"/>
</Context>

關鍵點:

  • JDBC 驅動 JAR(如 sqljdbc4.jar、ojdbc8.jar)必須放在 $CATALINA_HOME/lib,不可 放在專案 WEB-INF/lib(類別載入器隔離)
  • 屬性值間以空格分隔,嚴禁包含中文註解

步驟 2:web.xml 宣告 resource-ref

<resource-ref>
  <res-ref-name>jdbc/news</res-ref-name>
  <res-type>javax.sql.DataSource</res-type>
  <res-auth>Container</res-auth>
</resource-ref>

步驟 3:程式碼透過 JNDI 查找

Context initCtx = new InitialContext();
DataSource ds = (DataSource) initCtx.lookup("java:comp/env/jdbc/news");
Connection conn = ds.getConnection();  // 從池借用
try (PreparedStatement ps = conn.prepareStatement("SELECT * FROM users");
     ResultSet rs = ps.executeQuery()) {
    // 業務邏輯
} finally {
    if (conn != null) conn.close();  // 歸還池中,非真正關閉
}

方案二:Spring 管理資料源(委託 JNDI 或直接配置)

模式 A:Spring 透過 JNDI 查找 Tomcat 資料源

<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
  <property name="jndiName" value="java:comp/env/jdbc/news"/>
  <property name="proxyInterface" value="javax.sql.DataSource"/>
</bean>

模式 B:Spring 直接配置連線池(不依賴 Tomcat),以 HikariCP 為例

<bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource">
  <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/news?useSSL=false&serverTimezone=UTC"/>
  <property name="username" value="root"/>
  <property name="password" value="secret"/>
  <property name="maximumPoolSize" value="20"/>
  <property name="minimumIdle" value="5"/>
  <property name="idleTimeout" value="300000"/>
  <property name="connectionTestQuery" value="SELECT 1"/>
</bean>

HikariCP 為目前效能最優、API 最簡潔的連線池,Spring Boot 2.x 預設即採用之。

DAO 整合 JdbcTemplate

@Repository
public class UserDao extends JdbcDaoSupport {
    @Autowired
    public void setDs(DataSource dataSource) { setDataSource(dataSource); }

    public int countUsers() {
        return getJdbcTemplate().queryForObject("SELECT COUNT(*) FROM users", Integer.class);
    }
}

進階優化清單

  1. 啟用 PreparedStatement 快取:poolPreparedStatements=true + maxPoolPreparedStatementPerConnectionSize=20
  2. 連線洩漏偵測:logAbandoned=true + removeAbandonedTimeout=60
  3. 監控指標:整合 Micrometer + Prometheus 監控 hikaricp.connections.active/idle/pending
  4. 資料庫端配合:調整 max_connections、wait_timeout、interactive_timeout 避免資料庫主動斷開

常見坑點避雷

  • 驅動 JAR 放錯位置 → ClassNotFoundException 或 Cannot create JDBC driver
  • JNDI 名稱前綴寫錯 → 必須為 java:comp/env/ + resource-ref 名稱
  • 未關閉 ResultSet/Statement → 連線無法正確歸還,池耗盡
  • 長事務持有連線 → 縮短事務邊界,業務邏輯與資料庫操作分離
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
參數含義建議值
maxActive / maxTotal池中最大活躍連線數應用伺服器執行緒數 × 1.5
maxIdle池中最大閒置連線數≈ maxActive × 0.3
minIdle池中最小閒置連線數預熱數量,避免冷啟動延遲
maxWait / maxWaitMillis借用連線最長等待時間(毫秒)3000~10000,防止無限阻塞
validationQuery驗證連線有效性的 SQLMySQL: SELECT 1 / Oracle: SELECT 1 FROM DUAL
testOnBorrow / testWhileIdle借用/閒置時是否驗證建議開啟 testWhileIdle + evictor 執行緒