自定义数据库连接池

2,115 阅读4分钟
  • 自动初始化
  • 自动增长
  • 自动缩减



第一步,确保数据连接池单例加载

public class ConnectionPool {
	//需要单例创建的连接池
	private static volatile ConnectionPool pool;
	//私有化构造
	private ConnectionPool() {		
		if(pool != null) {
			throw new RuntimeException("连接池不可重复创建");
		}
	}
	//懒汉双检锁
	public static ConnectionPool getPool() {
		if(pool==null) {
			synchronized (ConnectionPool.class) {
				if(pool==null) {
					pool = new ConnectionPool();
				}
			}
		}
		return pool;
	}

}


第二步,加载数据库连接信息,读取配置文件

public class ConnectionPool {

	//其余的成员变量:数据库连接信息
	private static String driver;    //驱动
	private static String username;    //用户名
	private static String password;    //密码
	private static String url;        //数据库连接地址
	//初始数据库连接数
	private static int initCount = 5;
	//最小连接数量
	private static int minCount = 3;
	//最大连接数量
	private static int maxCount = 15;
	//存放连接的集合
        private static LinkedList pollCollection = new LinkedList<Connection>();
	static {
		//静态加载配置文件信息
		Properties properties = new Properties();
		try {    
                        //读取配置文件
			properties.load(ConnectionPool.class.getClassLoader()
					.getResourceAsStream("jdbcconfig.properties"));
			//赋值
			driver = properties.getProperty("jdbc.driver");
			username = properties.getProperty("jdbc.username");
			password = properties.getProperty("jdbc.password");
			url = properties.getProperty("jdbc.url");
                        //如果不设置最大最小连接数,则使用默认配置
			try {
				initCount = new Integer(properties.getProperty("jdbc.initCount"));
			} catch (NumberFormatException e) {
				initCount = 5;
				System.out.println("initCount使用默认值");
			}
			try {
				minCount = new Integer(properties.getProperty("jdbc.minCount"));
			} catch (NumberFormatException e) {
				minCount = 3;
				System.out.println("minCount使用默认值");
			}
			try {
				maxCount = new Integer(properties.getProperty("jdbc.maxCount"));
			} catch (NumberFormatException e) {
				maxCount = 5;
				System.out.println("maxCount使用默认值");
			}
			
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}



初始化连接池

/**
	 * 初始化连接池
	 * @return
	 */
	private void initPool() {	
		for(int i = 0;i<initCount;i++) {
			boolean flag = pollCollection.add(creat());
			if(flag==true) {
				currentCount++;
			}
			
		}
		
	}
	
	/**
	 * 
	 * @return 数据库创建连接
	 */
	private Connection creat() {
		try {
			//加载驱动
			Class.forName(driver);
			//建立连接
			Connection connection = DriverManager.getConnection(url, username, password);
			return connection;
		} catch (Exception e) {
			throw new RuntimeException("连接创建失败:"+e.getMessage());
		}
		
	}


自动增长

/**
	 * 连接自动增长,在池中没有连接时调用
	 */
	public synchronized void addAuto() {
		if(currentCount==maxCount) { //判断当前连接是否达到最大值
			throw new RuntimeException("当前连接数已达到最大值");
			
		}
		//增长步长为2
		for(int i = 0;i<2;i++) {//判断当前连接是否达到最大值
			if(currentCount == maxCount) {
				break;
			}
			poolCollection.add(creat());
			currentCount++;
		}
	}

获取池中连接

/**
	 * 获取池中连接
	 * @return
	 */
	public Connection getConn() {
		if(poolCollection.size()>0) {
			return poolCollection.removeFirst();
		}
		if(currentCount < maxCount) {
			addAuto();
			return getConn();//递归调用自身
		}
		//如果当前连接数已经达到最大,等一会再获取
		if(currentCount==maxCount) {
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		return getConn();    //递归
	}


池中连接自动缩减的方法

/**
	 * 自动缩减连接
	 */
	public void reduce() {
		// 如果当前连接数量大于最小连接数
		// 并且池中有空闲连接
		if (currentCount > minCount && poolCollection.size() > 0) {
			Connection con = poolCollection.removeFirst();
			try {
				con.close();
				con = null;
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

		}
	}


还回连接

	/**
	 * 还回连接
	 * @param conn
	 */
	public void returnConn(Connection conn) {
		poolCollection.add(conn);
		reduce();
	}


整体代码

package jdbctest;

import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.LinkedList;
import java.util.Properties;
import java.util.concurrent.ConcurrentLinkedQueue;

public class ConnectionPool {
	// 需要单例创建的连接池
	private static volatile ConnectionPool pool;

	// 其余的成员变量:数据库连接信息
	private static String driver;
	private static String username;
	private static String password;
	private static String url;
	// 初始数据库连接数
	private static int initCount = 5;
	// 最小连接数量
	private static int minCount = 3;
	// 最大连接数量
	private static int maxCount = 15;
	private static int currentCount = 0;
	private static LinkedList<Connection> poolCollection = new LinkedList<Connection>();

	static {
		// 静态加载配置文件信息
		Properties properties = new Properties();
		try {
			properties.load(ConnectionPool.class.getClassLoader().getResourceAsStream("jdbcconfig.properties"));

			driver = properties.getProperty("jdbc.driver");
			username = properties.getProperty("jdbc.username");
			password = properties.getProperty("jdbc.password");
			url = properties.getProperty("jdbc.url");
			try {
				initCount = new Integer(properties.getProperty("jdbc.initCount"));
			} catch (NumberFormatException e) {
				initCount = 5;
				System.out.println("initCount使用默认值");
			}
			try {
				minCount = new Integer(properties.getProperty("jdbc.minCount"));
			} catch (NumberFormatException e) {
				minCount = 3;
				System.out.println("minCount使用默认值");
			}
			try {
				maxCount = new Integer(properties.getProperty("jdbc.maxCount"));
			} catch (NumberFormatException e) {
				maxCount = 5;
				System.out.println("maxCount使用默认值");
			}

		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	private ConnectionPool() {

		if (pool != null) {
			throw new RuntimeException("连接池不可重复创建");
		}
		//初始化连接池
		initPool();
	}

	public static ConnectionPool getPool() {
		if (pool == null) {
			synchronized (ConnectionPool.class) {
				if (pool == null) {
					pool = new ConnectionPool();
				}
			}
		}
		return pool;
	}

	/**
	 * 初始化连接池
	 * 
	 * @return
	 */
	private void initPool() {
		for (int i = 0; i < initCount; i++) {
			boolean flag = poolCollection.add(creat());
			if (flag == true) {
				currentCount++;
			}

		}

	}

	/**
	 * 
	 * @return 数据库创建连接
	 */
	private Connection creat() {
		try {
			// 加载驱动
			Class.forName(driver);
			// 建立连接
			Connection connection = DriverManager.getConnection(url, username, password);
			return connection;
		} catch (Exception e) {
			throw new RuntimeException("连接创建失败:" + e.getMessage());
		}

	}

	/**
	 * 返回连接池中数量
	 * 
	 * @return
	 */
	public int getCount() {
		return currentCount;

	}

	/**
	 * 连接自动增长
	 */
	public synchronized void addAuto() {
		if (currentCount == maxCount) { // 判断当前连接是否达到最大值
			throw new RuntimeException("当前连接数已达到最大值");

		}
		// 增长步长为2
		for (int i = 0; i < 2; i++) {// 判断当前连接是否达到最大值
			if (currentCount == maxCount) {
				break;
			}
			poolCollection.add(creat());
			currentCount++;
		}
	}

	/**
	 * 获取池中连接
	 * 
	 * @return
	 */
	public Connection getConn() {
		if (poolCollection.size() > 0) {
			return poolCollection.removeFirst();
		}
		if (currentCount < maxCount) {
			addAuto();//连接池自动增长
			return getConn();// 递归调用自身
		}
		// 如果当前连接数已经达到最大,等一会再获取
		if (currentCount == maxCount) {
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		return getConn();
	}

	/**
	 * 自动缩减连接
	 */
	public void reduce() {
		// 如果当前连接数量大于最小连接数
		// 并且池中有空闲连接
		if (currentCount > minCount && poolCollection.size() > 0) {
			Connection con = poolCollection.removeFirst();
			try {
				con.close();
				con = null;
				currentCount--;
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

		}
	}

	/**
	 * 还回连接
	 * @param conn
	 */
	public void returnConn(Connection conn) {
		poolCollection.add(conn);
		reduce();
	}

}



jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.username=root
jdbc.password=root
jdbc.url=jdbc:mysql://localhost:3306/database
jdbc.initCount=8
jdbc.maxCount=15
...