当我们访问一个网站的时候,每访问一次都要连接该网站的数据库,这样每一次连接的创建和释放都消耗很大的服务器性能,所以就得有一个更好的数据库连接技术来解决这个性能问题。
以下只是实现了简单的创建连接,获得连接,释放连接,用来理解数据库连接池的原理
public class MyDataSource {
// 两个数据库连接池
// 一个空闲连接池,一个正在使用的连接池
private static LinkedList<Connection> freeConnections = new LinkedList<Connection>();
private static LinkedList<Connection> usingConnections = new LinkedList<Connection>();
private static int minCount = 10; // 最小连接数
private static int maxCount = 100;// 最大连接数
private static int currentCount;// 当前连接数
// 加载数据库驱动
static {
try {
Class.forName("com.mysql.jdbc.Driver");
// 创建10个连接放入到空闲连接池中
for (int i = 0; i < minCount; i++) {
Connection conn = createConnection();
freeConnections.add(conn);
currentCount++;
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
// 创建连接
public static Connection createConnection() throws SQLException {
Connection conn = DriverManager
.getConnection(
"jdbc:mysql://localhost/demo?useUnicede=true&characterEncoding=utf8",
"root", "root");
return new ConnectionWrap(conn);// 对连接进行包装
}
// 获得连接
public synchronized static Connection getConnection() throws SQLException {
if (freeConnections.size() > 0) {// 空闲连接池中有空闲连接
Connection conn = freeConnections.removeFirst();// 从空闲连接池中删除
usingConnections.add(conn);// 添加到正在使用的连接池
return conn;
} else {// 空闲连接池中没有空闲连接
if (currentCount < maxCount) {// 如果当前连接数在最大连接数之内
// 创建新的连接
Connection conn = createConnection();
currentCount++;
usingConnections.add(conn);
return conn;
} else {// 超出最大连接数
throw new RuntimeException("数据库炸了,不能在创建更多的连接");
}
}
}
// 释放连接
public synchronized static void giveBack(Connection conn) {
usingConnections.remove(conn);
freeConnections.add(conn);
}
}
有一个问题。当我们要关闭连接的时候。如果直接用conn.close()方法进行关闭连接的话,这个连接不会归还给连接池。
有一种解决方式。就是装饰者模式对连接进行包装
ConnectionWrapper 类 implements Connection接口
实现close()方法
public void close() throws SQLException {
MyDataSource.giveBack(this);
}
就是当用户调用close()方法时,调用MyDataSource类的giveBack()把连接释放并放入空闲连接池