| 分類 | 說明 |
|---|---|
| 名稱 | DBCP |
| 全稱 | Database Connection Pool |
| 功能 | 數(shù)據(jù)庫連接池 |
連接池
數(shù)據(jù)庫連接池是一種關(guān)鍵有限且昂貴的資源,對數(shù)據(jù)庫連接的管理能顯著影響整個應(yīng)用程序的伸縮性和健壯性,是影響程序的性能指標(biāo)。
數(shù)據(jù)庫連接池負(fù)責(zé)分配、管理、釋放數(shù)據(jù)庫連接,它允許應(yīng)用程序重復(fù)使用一個現(xiàn)有的數(shù)據(jù)庫連接,而不是重新建立一個。通過釋放空閑時間超過最大空閑時間的數(shù)據(jù)庫連接,來避免因為沒有釋放數(shù)據(jù)庫連接而引發(fā)的數(shù)據(jù)庫連接遺漏。
數(shù)據(jù)庫連接池的基本思想是在系統(tǒng)初始化時,將數(shù)據(jù)庫連接作為對象存儲在內(nèi)存中,當(dāng)用戶需要訪問數(shù)據(jù)庫時,并非建立一個新的連接,而是從連接池中取出一個已建立的空閑連接對象。當(dāng)使用完畢后,用戶也并非將連接關(guān)閉,而是將連接放回到連接池中,供下一個請求訪問使用。因此連接的建立、斷開都是由連接池自身來管理的。同時,可通過設(shè)置連接池參數(shù)來控制連接池中初始連接數(shù),連接的上下限數(shù)、每個連接的最大使用次數(shù)、最大空閑時間等,通過自身的管理機制來監(jiān)視數(shù)據(jù)庫連接的數(shù)量和使用情況等。
DBCP
- DBCP是一個依賴Jakarta commons-pool對象池機制的數(shù)據(jù)庫連接池
- DBCP是一個開源的連接池,是Apache Common成員之一,企業(yè)開發(fā)中常見,是Tomcat內(nèi)置的連接池。
- Spring開發(fā)組推薦使用DBCP,阿里的Druid也是參照DBCP開發(fā)而來的。
- DBCP支持通過JNDI獲取數(shù)據(jù)庫,并支持JTA或XA事務(wù)中用于2PC(兩階段提交)的連接對象。
下載地址 http://commons.apache.org/proper/commons-dbcp/download_dbcp.cgi
配置參數(shù) http://commons.apache.org/proper/commons-dbcp/configuration.html
接口文檔 https://tool.oschina.net/apidocs/apidoc?api=dbcp
依賴
Maven項目導(dǎo)入DBCP依賴
$ vim pom.xml
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-dbcp2</artifactId>
<version>2.6.0</version>
</dependency>
commons-dbcp2包依賴于commons-pool2包提供的底層對象池機制。
DBCP現(xiàn)有三種不同版本,支持不同版本的JDBC。
| DBCP | JDBC | Java |
|---|---|---|
| DBCP2 | JDBC4.1 | Java7 |
| DBCP1.4 | JDBC4 | Java6 |
| DBCP1.3 | JDBC3 | Java1.4.5 |
使用步驟
- 創(chuàng)建配置文件dbcp.properties用于設(shè)置數(shù)據(jù)庫連接參數(shù)和連接池參數(shù)等。
- 使用BasicDataSourceFactory加載dbcp.properties文件以獲取BasicDataSource對象
- 使用BasicDataSource對象獲取Connection連接對象
- 使用Connection連接對象對數(shù)據(jù)表操作
配置文件
$ vim resources/dbcp.properties
#連接基本屬性
driverClassName=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/fw?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&useSSL=true
connectionProperties=useUnicode=true;characterEncoding=utf8
username=root
password=root
#連接池大小和連接超時參數(shù)
initialSize=0
maxTotal=8
maxIdle=8
minIdle=0
maxWaitMillis=-1
| 基本配置 | 說明 |
|---|---|
| driverClassName=com.mysql.cj.jdbc.Driver | 要使用的JDBC驅(qū)動程序的完全限定的Java類名稱 |
| url=xxx | 連接的路徑,通過驅(qū)動創(chuàng)建所需的連接。 |
| connectionProperties | JDBC驅(qū)動建立連接時附帶的連接屬性,屬性格式[屬性名=property;]。 |
| username=root | 連接的用戶名,通過驅(qū)動創(chuàng)建需的連接。 |
| password=root | 連接的密碼,通過驅(qū)動創(chuàng)建所需的連接。 |
| 連接池 | 說明 |
|---|---|
| initialSize=0 | 初始化連接數(shù)量,連接池啟動時創(chuàng)建的。 |
| maxTotal=8 | 最大活動連接數(shù)量,連接池在同一時間能夠分配的最大活動連接的數(shù)量, 負(fù)數(shù)表示不限制。 |
| maxIdle=8 | 最大空閑連接,連接池中容許保持空閑狀態(tài)的最大連接數(shù)量,超過的空閑連接將被釋放,負(fù)數(shù)表示不限制。 |
| minIdle=0 | 最小空閑連接,連接池中容許保持空閑狀態(tài)的最小連接數(shù)量,低于這個數(shù)量將創(chuàng)建新的連接,0表示不創(chuàng)建。 |
| maxWaitMillis=-1 | 最大等待毫秒時間,當(dāng)沒有可用連接時,連接池等待連接被歸還的最大時間,超過則拋出異常,小于等于0表示無限等待。 |
工具類
$ vim util/DBCPUtil.java
package com.jc.util;
import org.apache.commons.dbcp2.BasicDataSourceFactory;
import javax.sql.DataSource;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;
public class DBCPUtil {
private static DataSource ds = null;
static {
//導(dǎo)入配置文件
Properties p = new Properties();
InputStream is = DBCPUtil.class.getClassLoader().getResourceAsStream("dbcp.properties");
try {
p.load(is);
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
//獲取數(shù)據(jù)源
try {
ds = BasicDataSourceFactory.createDataSource(p);
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
private static DataSource getDataSource(){
return ds;
}
//獲取連接
public static Connection getConnection(){
try {
return ds.getConnection();
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
//釋放連接返還連接池
public static void release(Connection conn, Statement stmt, ResultSet rs){
if(rs != null){
try{
rs.close();
}catch (Exception e) {
e.printStackTrace();
}
rs = null;
}
if(stmt != null){
try{
stmt.close();
}catch (Exception e) {
e.printStackTrace();
}
stmt = null;
}
if(conn != null){
try{
conn.close();
}catch (Exception e) {
e.printStackTrace();
}
conn = null;
}
}
}
測試
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
conn = DBCPUtil.getConnection();
System.out.println(conn);
String sql = "SELECT * FROM sys_user WHERE 1=1 AND id = ?";
ps = conn.prepareStatement(sql);
System.out.println(ps);
ps.setString(1, "4");
rs = ps.executeQuery();
System.out.println(rs);
while(rs.next()){
System.out.println(rs.getString("id"));
}
} catch (SQLException e) {
e.printStackTrace();
}finally {
DBCPUtil.release(conn, ps, rs);
}