自定义实现jdbc数据库连接池

连接池作用

  • 达到资源的复用
  • 提高响应速度(不必要的连接与关闭)
  • 资源的分配策略,可以统一管理

连接池的大致实现思路

  • 核心参数:
    空闲连接数: 没有使用的连接数
    活动连接数: 正在使用的连接数
    最大连接数: 最多允许存在的连接数
  • 初始化连接池(用容器封装:比如Vecotr sql包下)
  • 实现获取Connection的方法:
    (1) 判断当前连接数(countPool) 是否小于 最大连接数
    如果当前连接数 小于最大连接数
    则 判断空闲连接池中是否有连接可用, 有则直接使用 (可判断当前获取的连接是否存活)
    否则: 创建一个连接进行使用
    (2)当前连接数大于了 最大连接数
    则放入执行线程的任务进行等待
  • 释放连接,回收连接数机制
    (1) 判断当前空闲连接池 中的连接数是否小于 最大空闲连接数
    若小于, 则存放于空闲连接池
    否则: 直接关闭改连接

1.定义 连接池接口

自定义实现jdbc数据库连接池

2. 简易的封装一个连接池各个参数的Bean(可通过配置文件获取)

自定义实现jdbc数据库连接池

3. 实现数据库连接池

自定义实现jdbc数据库连接池

4. 封装连接池,对外提供访问

自定义实现jdbc数据库连接池

5. 测试

自定义实现jdbc数据库连接池

6. 结果

自定义实现jdbc数据库连接池

有重复利用数据库连接

7.核心类代码

/**
 * 实现思路:
 * 	关键参数: 空闲连接 , 活动连接, 最大连接
 * 1. 初始化连接, 连接安全问题 Vector<Connection> 
 * 2. 实现获取连接的方法
 * 3. 回收连接机制(回收资源)
 * @author xzb
 *
 */
public class ConnectionPool implements IConnectionPool {
	/**存放空闲连接数*/
	private static List<Connection> freePool = new Vector<Connection>();
	/**当前正在运行的连接数*/
	private static List<Connection> activePool = new Vector<Connection>();
	
	/**
	   * 记录当前线连接总数
	 */
	private static AtomicInteger countPool = new AtomicInteger();
	
	/**队列存放任务*/
	private static BlockingQueue<Connection> linkedBlockingQueue = new LinkedBlockingQueue<Connection>();
	
	/**读取配置文件*/
	private DbBean dbBean;
	
	public ConnectionPool(DbBean dbBean) {
		try {
			this.dbBean = dbBean;
			initPool();
		} catch (Exception e) {
		}
	}
	
	/**
	 * 初始化连接
	 */
	private void initPool() throws Exception {
		if (this.dbBean == null) {
			throw new Exception("连接");
		}
		for (int i = 0; i < this.dbBean.getInitConnections(); i++) {
			// 创建连接
			Connection connection = createConnection();
			freePool.add(connection);
		}
	}

	/**
	 *  创建数据库连接
	 * @throws SQLException 
	 * @throws ClassNotFoundException 
	 */
	private Connection createConnection() {
		try {
			Class.forName(this.dbBean.getDriverName());
			Connection connection = DriverManager.getConnection(this.dbBean.getUrl(), this.dbBean.getUserName(), this.dbBean.getPassword());
			countPool.incrementAndGet();
			return connection;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		} 
		
	}

	/**
	 * 获取连接
	 */
	public synchronized Connection getConnection() {
		Connection connection = null;
		try {
			// 当前连接数小于 最大允许的线程数
			if (countPool.get() < this.dbBean.getMaxActiveConnections()) {
				// 判断空闲连接池是否还有
				if (freePool.size() > 0 ) { 
					// 有,则直接从空闲池中获取
					connection = freePool.remove(0);
				}else {
					// 创建
					connection = createConnection();
				}
				// 判断当前线程是否可用
				if (!isAccessable(connection)) {
					// 当前连接都没有存活,则创建一个返回
					if (countPool.get() <= 0) {
						connection = createConnection();
					}
					// 当前空闲数-1
					countPool.decrementAndGet();
					getConnection();
				} else {
					activePool.add(connection);
					// countPool.incrementAndGet();
				}
			} else {
				// 当前没有可用连接,存入队列,等待
				this.wait(dbBean.getConnTimeOut());
				// 重试
				getConnection();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return connection;
	}

	/**
	   *   判断当前连接是否存活
	 */
	private boolean isAccessable(Connection connection) throws SQLException {
		if (connection == null || connection.isClosed()) {
			return false;
		}
		return true;
	}

	/**
	 * 连接回收机制
	 */
	public synchronized Boolean reselveConnection(Connection connection) {
		try {
			if (isAccessable(connection)) {
				// 可用, 判断是否放回空闲线程池中
				if (freePool.size() < this.dbBean.getMaxConnections()) {
					// 空闲线程池 小于最大空闲线程池容量, 则回收
					freePool.add(connection);
				} else {
					countPool.decrementAndGet();
					connection.close();
				}
				// 正在运行的连接移除
				activePool.remove(connection);
				// 唤醒
				this.notifyAll();
			} else {
				// 不可用,直接关闭
				if (connection != null ) {
					countPool.decrementAndGet();
					connection.close();
				}
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return null;
	}

}