java 创建自定义数据库连接池

设计思路:
1.连接实例

package com.example.deno.connectionPoolDemo;

import java.sql.Connection;

public class ConnectionExample {
	private boolean busy = true;//判断是否可用
	private boolean extra;//是否是额外连接
	private Connection con = null;
	
	public ConnectionExample(Connection conn) {
		this.con=conn;
	}

	public Connection getCon() {
		return con;
	}

	public boolean isBusy() {
		return busy;
	}

	public void setBusy(boolean busy) {
		this.busy = busy;
	}

	public boolean isExtra() {
		return extra;
	}

	public void setExtra(boolean extra) {
		this.extra = extra;
	}
	
}

2.连接池实例

package com.example.deno.connectionPoolDemo;

import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Iterator;
import java.util.Vector;

public class ConnectionPool {
	private int maxConnection=11; //最大连接数
	private String jdbcDriver = ""; // 数据库驱动
    private String dbUrl = ""; // 数据 URL
    private String dbUsername = ""; // 数据库用户名
    private String dbPassword = ""; // 数据库用户密码
    private int initialConnections = 10; // 连接池的初始大小
    private int incrementalConnections = 5; // 连接池自动增加的大小
	private Vector<ConnectionExample> v = null;//连接集合
	
	//为了测试遍历连接集合
	public Vector<ConnectionExample> getV() {
		return v;
	}

	public ConnectionPool(String jdbcDriver,String dbUrl,String dbUsername,String dbPassword) {
		this.dbPassword= dbPassword;
		this.jdbcDriver = jdbcDriver;
		this.dbUrl = dbUrl;
		this.dbUsername = dbUsername;
	}
	
	/**
	 * 第二步:创建连接池
	 */
	public synchronized void createPool() {
		if(v !=null) {
			return;
		}
		try {
			//实例化数据库驱动
			driverNewInstance(this.jdbcDriver);
			v = new Vector<>();
			//创建连接池的初始化连接,并存放在Vector向量中
			for(int x = 0 ;x<this.initialConnections;x++) {
				Connection conn = newConnection();
				ConnectionExample  ce = new ConnectionExample(conn);
				ce.setExtra(false);
				v.addElement(ce); 
			}
		}catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	/**
	 *  第一步:创建连接
	 * @return
	 * @throws SQLException
	 */
	private Connection newConnection() throws SQLException {
		//创建连接
		Connection conn = DriverManager.getConnection(dbUrl, dbUsername, dbPassword);
        System.out.println("创建数据库连接成功");
		return conn;
	}
	
	/**
	 * 获取连接
	 */
	public synchronized Connection getConnection() {
		if(v==null) {
			System.out.println("连接池未创建,无法获取连接");
			return null;
		}
		Connection conn = getUseableConnection();
		if(conn==null) {
			/**
			 * 无可用连接,
			 * 方式一:连接数达到上线,等待别人释放连接后获取
			 * 方式二:在连接数未达到上线的情况下,创建5个新的链接
			 */
			if(v.size()>=this.maxConnection) {
				System.out.println("连接数已达最大,需要等待4000ms,再尝试获取连接");
				try {
					Thread.sleep(4000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				
			}else {
				System.out.println("当前连接数不够用,且还未达到最大连接数,开始创建新的5个连接");
				try {
					//自动增加5个连接
					for(int x =0;x<incrementalConnections;x++) {
						if(v.size()<this.maxConnection) {
							Connection connew = newConnection();
							ConnectionExample  ce = new ConnectionExample(connew);
							ce.setExtra(true);
							v.addElement(ce);
						}else {
							break;
						}
					}
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
			conn = getUseableConnection();
		}
		return conn;
		
	}
	
	/**
	 * 回收链接
	 * @param conn
	 */
	public void returnConnection(Connection conn) {
		if(v==null) {
			System.out.println("连接池未创建,无法回收连接");
		}
		 Iterator<ConnectionExample> enumerate = v.iterator();
		 while(enumerate.hasNext()) {
			 ConnectionExample ce = enumerate.next();
			 if(conn == ce.getCon()) {
				 ce.setBusy(true);
				 break;
			 }
		 }
	}
	
	/**
	 * 刷新连接池,处理掉额外创建的连接,回复初始连接数
	 */
	public synchronized void freshConnectionPool() {
		if(v==null) {
			System.out.println("连接池未创建,无法刷新");
		}
		 Iterator<ConnectionExample> enumerate = v.iterator();
		 while(enumerate.hasNext()) {
			 ConnectionExample ce = enumerate.next();
			 if(!ce.isBusy()) { //当前连接在使用中
				 try {
					Thread.sleep(5000);//等待5秒
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			 }
			 //是额外创建的连接,则销毁
			 if(ce.isExtra()) {
				 closeConnection(ce.getCon());
				 enumerate.remove();
			 }else {
				//是初始连接,将该线程设置为可用
				 ce.setBusy(true);
			 }
		 }
	}
	
	/**
	 * 关闭连接池
	 */
	 public synchronized void closeConnectionPool() {
		 if (v == null) {
            System.out.println(" 连接池不存在,无法关闭 !");
            return;
	     }
		 Iterator<ConnectionExample> it = v.iterator();
		 while(it.hasNext()) {
			 ConnectionExample ce = it.next();
			 if(!ce.isBusy()) { //连接为false不可用,正在使用
				 try {
					Thread.sleep(5000);//等待5秒
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			 }
			 closeConnection(ce.getCon());
			 it.remove();//纯remove(),只会使Vector集合为[ ] ,仍需要将v引用到null上了,以同意判断null值的条件
		 }
		 v = null;
	 }
	 
	 /**
	 * 销毁连接
	 * @param conn
	 */
	private void closeConnection(Connection conn) {
		try {
			conn.close();
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 获取可用的连接
	 * @return 
	 * @return 
	 * @return
	 */
	private Connection getUseableConnection() {
		ConnectionExample ce = v.stream().filter(one->one.isBusy()==true).findFirst().orElse(null);
		if(ce ==null) {
			System.out.println("无可用的连接");
			return null;
		}else {
			ce.setBusy(false);
			return ce.getCon();
		}
	}

	/**
	 * 实例化驱动
	 * @throws ClassNotFoundException 
	 * @throws IllegalAccessException 
	 * @throws InstantiationException 
	 * @throws SQLException 
	 */
	private void driverNewInstance(String jdbcDriver) throws InstantiationException, IllegalAccessException, ClassNotFoundException, SQLException {
		Driver driver = (Driver) Class.forName(this.jdbcDriver).newInstance();
		DriverManager.registerDriver(driver);
	}
}

3.将连接池实例进行封装

package com.example.deno.connectionPoolDemo;

import java.sql.Connection;
import java.util.Vector;

public class ConnectionPoolUtil implements Pool{
	private static String jdbcDriver = "com.mysql.jdbc.Driver"; // 数据库驱动
    private static String dbUrl = "XXXXXXXXXXXXXX"; // 数据 URL
    private static String dbUsername = xxxxxxxx"; // 数据库用户名
    private static String dbPassword = "xxxxxxx"; // 数据库用户密码
    
    private static ConnectionPool connPool = null;
    //简单是实现单例
    private static ConnectionPoolUtil instance = new ConnectionPoolUtil();
	private ConnectionPoolUtil(){};	
 	public static ConnectionPoolUtil getInstance(){
		return instance;
	}
 	
 	static{
		connPool = new ConnectionPool(jdbcDriver, dbUrl , dbUsername, dbPassword);
	}


	@Override
	public void initPool() {
		connPool.createPool();
	}

	@Override
	public Connection getConnection() {
		return connPool.getConnection();
	}

	@Override
	public void returnConnection(Connection conn) {
		connPool.returnConnection(conn);
	}

	@Override
	public void closeConnectionPool() {
		connPool.closeConnectionPool();
	}
	
	public Vector getConnectionVector() {
		return connPool.getV();
	}

	@Override
	public void refreshConnections() {
		connPool.freshConnectionPool();
	}
}


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值