在實際項目開發中,我們在操作數據庫時,大部分情況下都會使用到連接池技術。有關連接池技術的工作原理,相信大家都非常清楚,這里就不啰嗦了。使用連接池技術操作數據庫,主要目的還是在於高並發訪問數據庫時,能夠有效的提升數據庫的整體性能。目前比較流行的數據庫連接池技術主要有兩個: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 連接池技術的使用,總體來說使用起來很簡單,希望對大家有用。