文章目錄
1. JDBC連接池
實際開發中,獲得連接或釋放連接是非常耗費系統資源的,我們採用連接池技術來解決性能問題。
1.1 連接池概述
1.1.1 概念
用池來管理Connection,這樣可以重複利用Connection。我們通過池來獲取Connection,用完調用Connection的close(), 並不是真正的關閉,而是歸還池。
1.1.2 規範
java爲數據庫連接池提供了公共的接口:javax.sql.Datasource, 各個廠商應該在自己的連接池實現這個接口,方便程序切換不同的連接池。
1.2 自定義連接池
1.2.1 分析
- 創建連接池實現(數據源),並實現javax.sql.Datasource接口。本案例只使用到getConnection()方法,簡化本案例,自己提供方法,不實現接口。
- 提供一個集合,用於存放連接,刪除和添加操作多,選擇LinkedList。
- 初始化池,提供三個連接。
- 調用getConnection()獲得Connection,爲了保證當前連接只能給一個線程使用,連接從池中刪除。
- 當使用完,調用Connection的close()歸還連接給池。
1.2.2 代碼
package com.freedom.pool;
import java.sql.Connection;
import java.sql.DriverManager;
import java.util.LinkedList;
public class JdbcUtils {
private static final String url = "jdbc:mysql://localhost:3306/javaweb";
private static final String user = "root";
private static final String password = "258369";
// 創建池並初始化
private static LinkedList<Connection> pool = new LinkedList<>();
static {
try {
Class.forName("com.mysql.jdbc.Driver");
for (int i = 0; i < 3; i++) {
Connection connection = DriverManager.getConnection(url, user, password);
pool.add(connection);
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* @Description: 獲得連接
* @return
*/
public static Connection getConnection() {
return pool.removeFirst();
}
/**
* @Description: 釋放連接
* @param connection
*/
public static void release(Connection connection) {
if (connection != null) {
pool.addLast(connection);
}
}
}
1.3 自定義連接池:方法增強
1.3.1 需求
以上的缺點在於歸還連接時,必須調用release()方法。如果用戶調用連接的close(),將釋放資源,這樣可能連接池可能無連接使用。爲此需要將close()方法增強,使之具有歸還連接的功能。
1.3.2 實現方法
增強方法有繼承,裝飾者模式和動態代理,這裏使用裝飾者模式實現。
1.3.3 代碼
public class MyConnection implements Connection {
private Connection connection;
private LinkedList<MyConnection> pool;
public MyConnection(Connection connection, LinkedList<MyConnection> pool) {
this.connection = connection;
this.pool = pool;
}
@Override
public void close() throws SQLException {
// 方法增強
pool.addLast(this);
}
// 其他方法調用原來的方法
@Override
public <T> T unwrap(Class<T> iface) throws SQLException {
return connection.unwrap(iface);
}
//------這裏省略其他方法--------//
}
public class MyJdbcUtils {
private static final String url = "jdbc:mysql://localhost:3306/javaweb";
private static final String user = "root";
private static final String password = "258369";
// 創建池並初始化
private static LinkedList<MyConnection> pool = new LinkedList<>();
static {
try {
Class.forName("com.mysql.jdbc.Driver");
for (int i = 0; i < 3; i++) {
Connection connection = DriverManager.getConnection(url, user, password);
MyConnection myConnection = new MyConnection(connection, pool);
pool.add(myConnection);
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* @Description: 獲得連接
* @return
*/
public static Connection getConnection() {
return pool.removeFirst();
}
}