更新時間:2021-02-20 17:06:22 來源:動力節點 瀏覽1223次
用Java代碼操作數據庫,需要數據庫連接對象,一個用戶至少要用到一個連接。現在假設有成千上百萬個用戶,就要創建十分巨大數量的連接對象,這會使數據庫承受極大的壓力,為了解決這種現象,一種技術出現了,這就是JDBC連接池。
一、JDBC連接池原理
傳統方式創建和銷毀與數據庫的連接都需要消耗系統資源和時間,為了復用連接,代替傳統的頻繁占用系統資源和耗費時間的方式,便于管理連接,可以規定最大的連接數(控制應用服務器對數據庫的并發訪問),JDBC連接池就是用來解決這些問題的。
在要使用連接對象之前先創建好規定數量(根據服務器的負載能力制定)的連接對象存放到連接池(實現池子的方式一般是用鏈表結構的集合來實現)中。
當應用服務器需要連接對象的時候就從連接池中獲取,用完該連接對象時歸還連接對象到連接池中。當應用服務器需要連接對象而當前連接池中沒有連接對象可取時,就讓其先等待,如果等待超時還沒有獲取到連接對象,就新建一個連接對象給服務器讓其使用,用完后銷毀該創建的對象。
二、JDBC連接池的簡單實現
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.LinkedList;
import java.util.Properties;
public class MyPool {
private int initCount = 3; // 初始連接數
private int maxCount = 6; // 最大連接數
private int currentCount = 0; // 當前連接數
// 用于保存連接的鏈表集合
private LinkedList<Connection> pools = new LinkedList<Connection>();
// 參數
private static String driverClass;
private static String url;
private static String user;
private static String password;
// 初始化參數
static {
InputStream input = MyPool.class.getResourceAsStream("/jdbcConf.properties");
Properties prop = new Properties();
try {
prop.load(input);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
input.close();
} catch (IOException e) {
e.printStackTrace();
}
}
url = prop.getProperty("url");
user = prop.getProperty("user");
password = prop.getProperty("password");
driverClass = prop.getProperty("driverClass");
try {
Class.forName(driverClass);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
public MyPool() {
// 初始化連接
for(int i = 0; i < initCount; i++) {
pools.addFirst(createConn());
}
}
// 創建連接
private Connection createConn() {
Connection proxyConn = null;
try {
Connection conn = DriverManager.getConnection(url, user, password);
// 對conn進行動態代理
proxyConn = (Connection) Proxy.newProxyInstance(
conn.getClass().getClassLoader(),
conn.getClass().getInterfaces(),
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 如果當前連接數小于初始連接數,則關閉連接時將連接放回連接池
String methodName = method.getName();
if ("close".equals(methodName)) {
if (pools.size() < initCount) {
pools.addLast(conn);
return null;
}
currentCount--;
}
return method.invoke(conn, args);
}
}
);
currentCount++;
} catch (SQLException e) {
e.printStackTrace();
}
return proxyConn;
}
// 獲取連接
public Connection getConn() {
// 如果連接池中還有連接,那就直接獲取
if(pools.size() > 0) {
return pools.removeFirst();
}
// 如果連接池中沒有連接,就判斷是否達到最大連接數,如果沒有就新建連接
if(currentCount < maxCount) {
return createConn();
}
// 達到最大連接數,就拋出異常
throw new RuntimeException("達到最大連接數了!!!");
}
}
三、開源的JDBC連接池技術
Sun公司約定:如果是連接池技術,需要實現一個接口javax.sql.DataSource
DBCP和C3P0是兩個開源的連接池技術。下面我們做一下簡單的介紹:
1、DBCP
DBCP是Apache軟件基金組織下的開源連接池實現,Tomcat的連接池正是采用DBCP來實現的。
DBCP既可以與應用服務器整合使用,也可由應用程序獨立使用。
2、c3p0概述
Spring框架默認支持C3P0連接池技術。
C3P0連接池的核心類:ComboPooledDataSource
JDBC連接池的出現歸根結底還是為了解決應用服務器對數據庫的并發訪問和代替傳統的頻繁占用系統資源和耗費時間的方式。這門技術涉及到的東西遠比本文寫出來的要復雜的多,想要徹底弄明白其中的彎彎繞繞,建議觀看本站的JDBC教程,打好基礎,慢慢掌握JDBC的各種知識。
0基礎 0學費 15天面授
有基礎 直達就業
業余時間 高薪轉行
工作1~3年,加薪神器
工作3~5年,晉升架構
提交申請后,顧問老師會電話與您溝通安排學習