文章目录
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();
}
}