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

Java DBCP 資料庫連線池設定完整教學與範例

     編輯:Java 相關知識

前言

資料庫連線建立成本高,頻繁開關會嚴重拖慢應用效能。Apache Commons DBCP (Database Connection Pool) 是經典的連線池實作,本文將詳細說明如何在 Java 專案中整合 DBCP 2.x,涵蓋 Maven 依賴、核心配置參數、程式碼範例與效能調優建議。

Maven 依賴

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-dbcp2</artifactId>
    <version>2.9.0</version> <!-- 請檢查最新版本 -->
</dependency>
<!-- 資料庫驅動,以 MySQL 為例 -->
<dependency>
    <groupId>com.mysql</groupId>
    <artifactId>mysql-connector-j</artifactId>
    <version>8.0.33</version>
</dependency>

核心配置類別

package com.example.config;

import org.apache.commons.dbcp2.BasicDataSource;
import javax.sql.DataSource;
import java.sql.SQLException;

public class DBCPConfig {
    private static final BasicDataSource DATA_SOURCE = new BasicDataSource();

    static {
        // 基本連線資訊
        DATA_SOURCE.setDriverClassName("com.mysql.cj.jdbc.Driver");
        DATA_SOURCE.setUrl("jdbc:mysql://localhost:3306/mydb?useSSL=false&serverTimezone=UTC");
        DATA_SOURCE.setUsername("root");
        DATA_SOURCE.setPassword("password");

        // 連線池核心參數
        DATA_SOURCE.setInitialSize(5);           // 初始連線數
        DATA_SOURCE.setMinIdle(5);               // 最小閒置連線
        DATA_SOURCE.setMaxIdle(10);              // 最大閒置連線
        DATA_SOURCE.setMaxTotal(20);             // 最大連線數(舊版 maxActive)
        DATA_SOURCE.setMaxWaitMillis(30000);     // 取得連線最大等待時間(ms)

        // 連線驗證機制(關鍵:防止資料庫斷開導致的失效連線)
        DATA_SOURCE.setValidationQuery("SELECT 1");
        DATA_SOURCE.setTestOnBorrow(true);       // 借用時驗證
        DATA_SOURCE.setTestOnReturn(false);      // 歸還時驗證(通常關閉以提升效能)
        DATA_SOURCE.setTestWhileIdle(true);      // 閒置驗證
        DATA_SOURCE.setTimeBetweenEvictionRunsMillis(60000); // 驗證間隔
        DATA_SOURCE.setMinEvictableIdleTimeMillis(300000);   // 最小閒置存活時間

        // 其他優化
        DATA_SOURCE.setDefaultAutoCommit(true);
        DATA_SOURCE.setAccessToUnderlyingConnectionAllowed(true); // 允許取得原生連線
    }

    public static DataSource getDataSource() {
        return DATA_SOURCE;
    }

    public static void shutdown() throws SQLException {
        DATA_SOURCE.close();
    }
}

關鍵參數詳解

參數預設值建議值說明
initialSize05~10啟動時建立的連線數,減少首次請求延遲
maxTotal820~50池中最大連線數,視資料庫 max_connections 與應用併發調整
maxIdle810~20池中保留的最大閒置連線,超過者會被逐出
minIdle0同 initialSize最小閒置連線,低於此值會補充新連線
maxWaitMillis-1(無限等待)10000~30000連線耗盡時等待毫秒數,避免無限阻塞
validationQuery無SELECT 1驗證連線有效性的 SQL,MySQL 用 SELECT 1,Oracle 用 SELECT 1 FROM DUAL
testOnBorrowfalsetrue每次借用前執行 validationQuery,確保連線存活
testWhileIdlefalsetrue由背景執行緒定期檢查閒置連線
timeBetweenEvictionRunsMillis-130000~60000閒置連線驗證執行間隔

使用範例:DAO 中取得連線

package com.example.dao;

import com.example.config.DBCPConfig;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

public class UserDao {
    private final DataSource dataSource = DBCPConfig.getDataSource();

    public List<String> getAllUsernames() {
        String sql = "SELECT username FROM users";
        List<String> list = new ArrayList<>();

        // try-with-resources 自動關閉連線、Statement、ResultSet
        try (Connection conn = dataSource.getConnection();
             PreparedStatement ps = conn.prepareStatement(sql);
             ResultSet rs = ps.executeQuery()) {

            while (rs.next()) {
                list.add(rs.getString("username"));
            }
        } catch (SQLException e) {
            throw new RuntimeException("查詢失敗", e);
        }
        return list;
    }
}

Spring 整合配置 (XML)

<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">
    <property name="driverClassName" value="com.mysql.cj.jdbc.Driver" />
    <property name="url" value="jdbc:mysql://localhost:3306/mydb?useSSL=false&serverTimezone=UTC" />
    <property name="username" value="root" />
    <property name="password" value="password" />
    <property name="initialSize" value="5" />
    <property name="maxTotal" value="20" />
    <property name="maxIdle" value="10" />
    <property name="minIdle" value="5" />
    <property name="maxWaitMillis" value="30000" />
    <property name="validationQuery" value="SELECT 1" />
    <property name="testOnBorrow" value="true" />
    <property name="testWhileIdle" value="true" />
    <property name="timeBetweenEvictionRunsMillis" value="60000" />
    <property name="minEvictableIdleTimeMillis" value="300000" />
</bean>

Spring Boot 自動配置

Spring Boot 2.x 預設使用 HikariCP,若堅持用 DBCP2:

spring.datasource.type=org.apache.commons.dbcp2.BasicDataSource
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/mydb?useSSL=false&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=password
spring.datasource.dbcp2.initial-size=5
spring.datasource.dbcp2.max-total=20
spring.datasource.dbcp2.max-idle=10
spring.datasource.dbcp2.min-idle=5
spring.datasource.dbcp2.max-wait-millis=30000
spring.datasource.dbcp2.validation-query=SELECT 1
spring.datasource.dbcp2.test-on-borrow=true
spring.datasource.dbcp2.test-while-idle=true

效能監控與調優建議

  1. 啟用 JMX 監控:BasicDataSource 實作 ManagedDataSource,可透過 JConsole、VisualVM 觀察 NumActive、NumIdle、NumWaiting 指標。
  2. 避免連線洩漏:務必使用 try-with-resources 或 finally 區塊關閉 Connection,歸還池中。
  3. 調整 maxTotal:公式參考:maxTotal = (核心數 * 2) + 有效磁碟數,但受限於資料庫 max_connections。
  4. 考慮升級 HikariCP:HikariCP 效能更優、程式碼更精簡、預設配置更合理,Spring Boot 2.x+ 預設即採用。

常見問題排查

Communications link failure / Connection reset
資料庫斷開閒置連線。確保 testOnBorrow=true、validationQuery 正確,並檢查資料庫 wait_timeout (MySQL 預設 8 小時) 是否小於池的 minEvictableIdleTimeMillis。
Pool exhausted / Timeout waiting for idle object
併發過高或連線未歸還。檢查程式碼是否漏關連線、調大 maxTotal、優化慢查詢縮短佔用時間。
No suitable driver found
驅動類別名稱錯誤或驅動 JAR 未在 classpath。MySQL 8.0+ 用 com.mysql.cj.jdbc.Driver。

正確配置連線池是資料庫應用高效能穩定運行的基石,建議從預設值開始,結合壓力測試與監控指標逐步調優。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved