首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> DB2 資料庫 >> DB2 教學

C3P0 連接池入門指南:從零開始掌握 Java 資料庫連接池配置

     編輯:DB2 教學

什麼是 C3P0 連接池?

C3P0 是一個開源的 JDBC 連接池庫,它實現了資料源與 JNDI 綁定,支援 JDBC 3 規格及 JDBC 2 標準擴展。廣泛應用於 Hibernate、Spring 等主流開源框架中。簡單來說,連接池就像一個「連接水池」,預先建立好多個資料庫連接並存放其中,應用程式需要時直接取用,用完歸還,避免頻繁創建銷毀連接的性能開銷。

環境準備與依賴包

開始前,請確保專案已引入以下核心 JAR 包(版本號可根據實際情況調整):

  • c3p0-0.9.5.5.jar(核心包)
  • mchange-commons-java-0.2.19.jar(C3P0 依賴)
  • mysql-connector-java-8.0.xx.jar(MySQL 驅動,建議使用較新版本)
  • junit-4.13.x.jar(單元測試)

提示:原文提到的 commons-io-2.0.1.jar 並非 C3P0 必須,視專案需求決定是否引入。

資料庫與測試表準備

在 MySQL 中建立測試資料庫 test 及 user 表:

CREATE DATABASE IF NOT EXISTS `test` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
USE `test`;

DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
  `id` INT(10) NOT NULL AUTO_INCREMENT,
  `user_name` VARCHAR(20) DEFAULT NULL,
  `passWord` VARCHAR(100) DEFAULT NULL,
  `address` VARCHAR(100) DEFAULT NULL,
  `phone_number` VARCHAR(20) DEFAULT NULL,
  `create_time` DATETIME DEFAULT NULL,
  `update_time` DATETIME DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4;

INSERT INTO `user` (`id`,`user_name`,`passWord`,`address`,`phone_number`,`create_time`,`update_time`) VALUES
(1,'test','CY9rzUYh03PK3k6DJIE09g==','test','test','2014-03-29 00:48:14','2014-03-29 00:48:17'),
(2,'te2','CY9rzUYh03PK3k6DJIE09g==','asdfk','4156434885','2015-08-05 11:09:29','2015-08-20 11:09:33');

方式一:手動載入 Properties 配置文件

在 src/main/resources 下建立 db.properties:

jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/test?useSSL=false&serverTimezone=UTC
jdbc.username=root
jdbc.password=root

核心示例代碼:

package com.example.c3p0;

import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.junit.Test;

import java.beans.PropertyVetoException;
import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;

public class C3p0Demo1 {

    @Test
    public void getConnection() throws IOException, PropertyVetoException, SQLException {
        // 1. 載入配置文件
        Properties prop = new Properties();
        try (InputStream in = C3p0Demo1.class.getClassLoader().getResourceAsStream("db.properties")) {
            prop.load(in);
        }

        // 2. 建立並配置連接池
        ComboPooledDataSource cpds = new ComboPooledDataSource();
        cpds.setDriverClass(prop.getProperty("jdbc.driver"));
        cpds.setJdbcUrl(prop.getProperty("jdbc.url"));
        cpds.setUser(prop.getProperty("jdbc.username"));
        cpds.setPassword(prop.getProperty("jdbc.password"));

        // 3. 獲取連接並執行查詢
        try (Connection conn = cpds.getConnection();
             PreparedStatement ps = conn.prepareStatement("SELECT * FROM user");
             ResultSet rs = ps.executeQuery()) {

            while (rs.next()) {
                System.out.println("ID: " + rs.getInt("id"));
                System.out.println("用戶名: " + rs.getString("user_name"));
                System.out.println("密碼: " + rs.getString("passWord"));
                System.out.println("地址: " + rs.getString("address"));
                System.out.println("電話: " + rs.getString("phone_number"));
                System.out.println("創建時間: " + rs.getTimestamp("create_time"));
                System.out.println("更新時間: " + rs.getTimestamp("update_time"));
                System.out.println("-------------------------");
            }
        }
        // try-with-resources 自動關閉連接(歸還池中)、Statement、ResultSet
        // cpds.close() 應在應用關閉時調用,此處為演示省略
    }
}

關鍵點:conn.close() 並非真正關閉物理連接,而是將連接歸還給連接池。

方式二:使用 C3P0 原生配置文件(更簡潔)

在 src/main/resources 下建立 固定名稱 c3p0.properties,C3P0 會自動識別:

c3p0.driverClass=com.mysql.cj.jdbc.Driver
c3p0.jdbcUrl=jdbc:mysql://localhost:3306/test?useSSL=false&serverTimezone=UTC
c3p0.user=root
c3p0.password=root

# 連接池常用調優參數(可選)
c3p0.initialPoolSize=5
c3p0.minPoolSize=5
c3p0.maxPoolSize=20
c3p0.maxIdleTime=1800
c3p0.acquireIncrement=5

代碼極度簡化:

package com.example.c3p0;

import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.junit.Test;

import javax.sql.DataSource;
import java.sql.*;

public class C3p0Demo2 {

    @Test
    public void getConByC3P0() throws SQLException {
        // 無需手動讀取配置,C3P0 自動載入 c3p0.properties
        DataSource ds = new ComboPooledDataSource();

        try (Connection conn = ds.getConnection();
             PreparedStatement ps = conn.prepareStatement("SELECT * FROM user");
             ResultSet rs = ps.executeQuery()) {

            System.out.println("獲取到連接: " + conn);
            while (rs.next()) {
                System.out.println("ID: " + rs.getInt("id") + ", 用戶名: " + rs.getString("user_name"));
            }
        }
    }
}

常見連接池參數說明

參數說明建議值
initialPoolSize初始化連接數5-10
minPoolSize最小保持連接數5-10
maxPoolSize最大連接數20-50(視資料庫 max_connections)
maxIdleTime連接最大空閒時間(秒),超過則被釋放1800 (30分)
acquireIncrement連接不足時一次創建數量3-5
checkoutTimeout等待連接超時時間(毫秒)5000
testConnectionOnCheckout取出連接時驗證有效性true

最佳實踐總結

  1. 優先使用方式二:配置與代碼分離,維護性更好。
  2. 資源管理用 try-with-resources:JDK 7+ 自動關閉 Connection、Statement、ResultSet,避免洩漏。
  3. 連接池為單例:實際專案中 ComboPooledDataSource 應作為 Bean 由 Spring 管理,而非方法內 new。
  4. 監控指標:關注 numBusyConnections、numIdleConnections、numUnclosedOrphanedConnections 等運行時指標。

結語

掌握 C3P0 基礎配置後,建議進一步學習 HikariCP(目前 Spring Boot 2.x 默認連接池,性能更優)、Druid(阿里出品,監控強大)等新一代連接池,根據業務場景選型。

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