c3p0 數據庫連接池技術的使用


在實際項目開發中,我們在操作數據庫時,大部分情況下都會使用到連接池技術。有關連接池技術的工作原理,相信大家都非常清楚,這里就不啰嗦了。使用連接池技術操作數據庫,主要目的還是在於高並發訪問數據庫時,能夠有效的提升數據庫的整體性能。目前比較流行的數據庫連接池技術主要有兩個:c3p0 和 druid。這里我們先以操作 mysql 數據庫為例,快速簡單總結一下 c3p0 數據庫連接池技術的使用。

c3p0 的官網地址:https://www.mchange.com/projects/c3p0


一、配置 c3p0 連接池

我們首先創建一個 JavaSE 的 Maven 項目,在 pom.xml 文件中導入 c3p0 和 mysql 的 jar 包。

有關各種 jar 包依賴的 xml 配置內容,可以從 https://mvnrepository.com 上進行查找,復制粘貼到 pom.xml 即可。
c3p0 的 jar 包網址是:https://mvnrepository.com/artifact/com.mchange/c3p0
mysql 連接 java 的驅動 jar 包網址是:https://mvnrepository.com/artifact/mysql/mysql-connector-java

我在 pom.xml 配置的都是當前最新版本的 jar 包,如下所示:

<!-- 導入 c3p0 的 jar 包 -->
<dependency>
    <groupId>com.mchange</groupId>
    <artifactId>c3p0</artifactId>
    <version>0.9.5.5</version>
</dependency>

<!-- 導入 mysql 的 jar 包 -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.28</version>
</dependency>

配置好引用的 jar 包后,打開右側的 Maven 窗口,刷新一下,這樣 Maven 會自動下載所需的 jar 包文件。

然后在項目的 resources 資源目錄下創建 c3p0 的配置文件(注意:c3p0 的配置文件的名稱必須是 c3p0-config.xml 或 c3p0-config.properties),這里我們使用 c3p0-config.xml 作為配置文件,內容如下所示:

<c3p0-config>
    <!-- 配置默認使用的連接池相關參數 -->
    <default-config>
        <!--  mysql 連接參數 -->
        <property name="driverClass">com.mysql.jdbc.Driver</property>
        <property name="jdbcUrl">jdbc:mysql://localhost:3306/testdb</property>
        <property name="user">root</property>
        <property name="password">123456</property>

        <!--初始化的連接數量-->
        <property name="initialPoolSize">5</property>
        <!--最大連接數量-->
        <property name="maxPoolSize">20</property>
        <!--獲取連接的等待超時時間(毫秒)-->
        <property name="checkoutTimeout">3000</property>
    </default-config>

    <!-- 根據實際業務需要,可以有多份具有名稱的參數配置 -->
    <!-- 這里增加了一份名稱為 other 的配置,連接的是本機另外一個數據庫 -->
    <named-config name="fastdb">
        <property name="driverClass">com.mysql.jdbc.Driver</property>
        <property name="jdbcUrl">jdbc:mysql://localhost:3306/fastdb</property>
        <property name="user">root</property>
        <property name="password">123456</property>

        <property name="initialPoolSize">10</property>
        <property name="maxPoolSize">50</property>
        <property name="checkoutTimeout">5000</property>
    </named-config>
</c3p0-config>

c3p0 的配置文件中,有一個默認參數配置,即 default-config 包裹的配置內容。另外也可以有多個命名的參數配置,即 named-config 包裹的內容,這里增加了一個名稱為 fastdb 的命名配置。當創建 c3p0 數據源對象 ComboPooledDataSource 時,如果沒有指定參數,使用的就是默認配置。如果指定了參數,則必須使用 named-config 中配置的名稱。


二、使用 c3p0 連接池

使用 c3p0 連接池,主要是創建出 ComboPooledDataSource 數據源對象,然后調用其 getConnection 方法獲取數據庫連接對象,拿到連接對象之后,其它的操作跟 JDBC 訪問數據庫的操作一模一樣,唯一的區別就是當調用連接的 close 方法時,底層不再是關閉銷毀連接對象,而是將連接對象放入到連接池中,以便后續新的請求到來時,直接拿去使用。具體代碼如下:

import com.mchange.v2.c3p0.ComboPooledDataSource;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class c3p0test {
    public static void main(String[] args) throws SQLException {

        //使用【默認的配置】創建 c3p0 的數據庫連接池對象
        DataSource dataSource = new ComboPooledDataSource();

        //使用【指定名稱的配置】創建 c3p0 的數據源對象
        //DataSource dataSource = new ComboPooledDataSource("fastdb");

        //通過數據源對象獲取數據庫連接
        //如果連接池中的連接已經被用完,則會等待一定的時間(所配置的時間)
        //如果等待超時,就會拋出異常
        Connection con = dataSource.getConnection();

        //執行 sql 語句,獲取並打印結果集
        String sql = "select e_id, e_name, e_age from employee";
        PreparedStatement pst = con.prepareStatement(sql);
        ResultSet rs = pst.executeQuery();
        while (rs.next()) {
            System.out.println(
                    rs.getInt("e_id") + "\t" +
                    rs.getString("e_name") + "\t" +
                    rs.getInt("e_age"));
        }

        //釋放資源
        rs.close();
        pst.close();

        //這里的關閉連接,並沒有關閉和銷毀連接
        //而是把連接對象,放入到連接池中,供后續訪問時直接拿去使用
        con.close();
    }
}

如果你之前基於 JDBC 編寫過通用的數據庫訪問類,那么將它改造為基於 c3p0 的數據庫訪問類,也是很容易的。
比如下面是一個簡單的基於 c3p0 的數據庫訪問類,只提供了獲取數據庫連接,以及關閉(歸還)數據庫連接的方法:

import com.mchange.v2.c3p0.ComboPooledDataSource;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class c3p0helper {

    private static DataSource dataSource;

    //靜態初始化,使用默認配置創建 c3p0 數據源對象
    static {
        dataSource = new ComboPooledDataSource();
    }

    //獲取數據庫連接
    public static Connection getConnection() {
        Connection con = null;
        try {
            con = dataSource.getConnection();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return con;
    }

    //釋放查詢操作相關的資源(結果集對象,SQL語句對象,歸還數據庫連接)
    public static void close(Connection con, Statement stat, ResultSet rs) {
        if (con != null) {
            try {
                con.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

        if (stat != null) {
            try {
                stat.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

        if (rs != null) {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

    //釋放增刪改相關操作的資源(SQL語句對象,歸還數據庫連接)
    public static void close(Connection con, Statement stat) {
        close(con, stat, null);
    }
}

然后使用這個簡單的 c3p0 數據庫訪問類,改造上面的代碼示例:

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class c3p0test {
    public static void main(String[] args) throws SQLException {

        Connection con = c3p0helper.getConnection();

        String sql = "select e_id,e_name,e_age from employee";
        PreparedStatement pst = con.prepareStatement(sql);

        ResultSet rs = pst.executeQuery();
        while (rs.next()) {
            System.out.println(
                    rs.getInt("e_id") + "\t" +
                    rs.getString("e_name") + "\t" +
                    rs.getInt("e_age"));
        }

        c3p0helper.close(con, pst, rs);
    }
}

OK,以上只是簡單的介紹了一下 c3p0 連接池技術的使用,總體來說使用起來很簡單,希望對大家有用。




免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM