欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

手写 基础 数据库连接池

程序员文章站 2022-05-12 17:09:21
...

手写数据库连接池 基础

 

 

package com.curiousby.baoyou.cn.showandshare.customised.dbpool.mysql;

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



public class MyCustomisedPool { 
	
	/**
	 * <pre>
	 * jdbcDriver = "com.mysql.jdbc.Driver"; // 数据库驱动
	 * dbUrl = "jdbc:mysql://localhost:3306/database"; // 数据 URL
	 * dbUsername = "root"; // 数据库用户名
	 * dbPassword = "root"; // 数据库用户密码
	 *  testSql = "select count(*) from t_user"; // 测试连接是否可用的测试表名,默认没有测试表
	 *  initialConnections = 10; // 连接池的初始大小
	 *  incrementalConnections = 5;// 连接池自动增加的大小
	 *  maxConnections = 50; // 连接池最大的大小
	 *  </pre>
	 * @author baoy
	 */
	private DBConfig conf;
	private Vector<CustomisedConnection> connections;
	
	public static class CustomisedConnection{
		
		private  boolean busy = false;
		private Connection Connection = null;
		 
		public CustomisedConnection(Connection connection) {
			Connection = connection;
		}
		
		public boolean isBusy() {
			return busy;
		}
		public void setBusy(boolean busy) {
			this.busy = busy;
		}
		public Connection getConnection() {
			return Connection;
		}
		public void setConnection(Connection connection) {
			Connection = connection;
		} 
	}
	
	/**
	 * <pre>
	 * jdbcDriver = "com.mysql.jdbc.Driver"; // 数据库驱动
	 * dbUrl = "jdbc:mysql://localhost:3306/database"; // 数据 URL
	 * dbUsername = "root"; // 数据库用户名
	 * dbPassword = "root"; // 数据库用户密码
	 *  testSql = "select count(*) from t_user"; // 测试连接是否可用的测试表名,默认没有测试表
	 *  initialConnections = 10; // 连接池的初始大小
	 *  incrementalConnections = 5;// 连接池自动增加的大小
	 *  maxConnections = 50; // 连接池最大的大小
	 *  </pre>
	 * @author baoy
	 */
	public static class DBConfig{
		private String jdbcDriver = "com.mysql.jdbc.Driver"; // 数据库驱动
		private String dbUrl = "jdbc:mysql://localhost:3306/database"; // 数据 URL
		private String dbUsername = "root"; // 数据库用户名
		private String dbPassword = "root"; // 数据库用户密码
		private String testSql = "select count(*) from t_user"; // 测试连接是否可用的测试表名,默认没有测试表
		private int initialConnections = 10; // 连接池的初始大小
		private int incrementalConnections = 5;// 连接池自动增加的大小
		private int maxConnections = 50; // 连接池最大的大小
		
		public String getJdbcDriver() {
			return jdbcDriver;
		}
		public void setJdbcDriver(String jdbcDriver) {
			this.jdbcDriver = jdbcDriver;
		}
		public String getDbUrl() {
			return dbUrl;
		}
		public void setDbUrl(String dbUrl) {
			this.dbUrl = dbUrl;
		}
		public String getDbUsername() {
			return dbUsername;
		}
		public void setDbUsername(String dbUsername) {
			this.dbUsername = dbUsername;
		}
		public String getDbPassword() {
			return dbPassword;
		}
		public void setDbPassword(String dbPassword) {
			this.dbPassword = dbPassword;
		}
		public String getTestSql() {
			return testSql;
		}
		public void setTestSql(String testSql) {
			this.testSql = testSql;
		}
		public int getInitialConnections() {
			return initialConnections;
		}
		public void setInitialConnections(int initialConnections) {
			this.initialConnections = initialConnections;
		}
		public int getIncrementalConnections() {
			return incrementalConnections;
		}
		public void setIncrementalConnections(int incrementalConnections) {
			this.incrementalConnections = incrementalConnections;
		}
		public int getMaxConnections() {
			return maxConnections;
		}
		public void setMaxConnections(int maxConnections) {
			this.maxConnections = maxConnections;
		}
	}
	
	
	
	
	
	
	
	
	
	




	private Connection newConnection() throws SQLException{
		Connection conn = DriverManager.getConnection(conf.dbUrl, conf.dbUsername, conf.dbPassword);
		if (this.connections == null || this.connections.size() == 0) {
			int driverMaxConnections = conn.getMetaData().getMaxConnections();
			if (conf.maxConnections > 0 && driverMaxConnections <  conf.maxConnections ) {
				conf.maxConnections  = driverMaxConnections;
			}
		}
		return  conn;
	}
	
	private void createConnection(int nums) throws SQLException{
		for (int i = 0; i < nums; i++) {
			// 1如果 最大连接数大于0  
			// 1.1 并且 当前连接数小于最大连接数 ,可以
			// 1.2   当前连接数大于最大连接数,跳出(或者抛出异常,超出最大连接数)
			// 2 如果 最大连接数小于0,无最大连接数限制 
			if (conf.maxConnections > 0 && this.connections.size()>= conf.maxConnections ) {
				break;
			}
			connections.add( new CustomisedConnection(newConnection()));
		}
	}
	 
	
	public synchronized  void  initConnection() throws SQLException, InstantiationException, IllegalAccessException, ClassNotFoundException{
		if (connections != null) {
			return;
		}
		Driver driver = (Driver) (Class.forName(conf.jdbcDriver).newInstance());
		DriverManager.registerDriver(driver);
		connections = new Vector<CustomisedConnection>();
		createConnection(conf.initialConnections);
	}
	
	private CustomisedConnection findFreeConnection() throws SQLException {
		Iterator<CustomisedConnection> iterator = connections.iterator();
		while (iterator.hasNext()) { 
			CustomisedConnection customisedConnection = iterator.next();
			if (!customisedConnection.isBusy()) {
				Connection connection = customisedConnection.getConnection();
				if (!testConnection(connection)) {
					connection = newConnection();
					customisedConnection.setConnection(connection);
				}
				customisedConnection.setBusy(true);
				return customisedConnection;
			}
		}
		return null;
	}
	
	private boolean testConnection(Connection connection) throws SQLException {
		if (conf.getTestSql() != null && !"".equals(conf.getTestSql())) {
			try{
			Statement stmt = connection.createStatement();
			stmt.execute(conf.getTestSql());
			}catch(Exception e){
				e.printStackTrace();
				closeConnection(connection); 
				return false;
			}
		}
		return true;
	}

	private  CustomisedConnection getFreeCustomisedConnection() throws SQLException { 
		CustomisedConnection findFreeConnection = findFreeConnection();
		if (findFreeConnection != null) {
			return findFreeConnection;
		}
		if (conf.maxConnections > 0 &&   conf.maxConnections  > connections.size() ) {
			int nums =  conf.maxConnections  > connections.size()+conf.incrementalConnections ? conf.incrementalConnections : conf.maxConnections-  connections.size();
			createConnection(nums);
		}
		return findFreeConnection();
	}

	
	public synchronized CustomisedConnection getConnection() throws SQLException{
		if (connections == null) {
			return null;
		}
		CustomisedConnection conn = getFreeCustomisedConnection();
		while (conn == null) {
			try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); }
			conn = getFreeCustomisedConnection();
		}
		return conn;
	}
	
	public synchronized void returnConnection(Connection conn){
		Iterator<CustomisedConnection> iterator = connections.iterator();
		while (iterator.hasNext()) { 
			CustomisedConnection customisedConnection = iterator.next();
			if (conn == customisedConnection.getConnection()) { 
				customisedConnection.setBusy(false);
			}
		}
	}
	 
	public synchronized void  closeConnection(Connection conn) {
		Iterator<CustomisedConnection> iterator = connections.iterator();
		while (iterator.hasNext()) { 
			CustomisedConnection customisedConnection = iterator.next();
			if (conn == customisedConnection) {  
				//设置成true 没有线程继续访问它
				customisedConnection.setBusy(true);
				//关闭连接
				Connection connection = customisedConnection.getConnection();
				try { connection.close(); } catch (SQLException e) {  e.printStackTrace(); }
				// 从池中移除
				connections.remove(customisedConnection);
			}
		} 
	}

	public int getPoolSize(){
		if (connections == null) {
			return 0;
		}
		return connections.size();
	} 
	 
	
	public DBConfig getConf() {
		return conf;
	}

	public void setConf(DBConfig conf) {
		this.conf = conf;
	}

	public Vector<CustomisedConnection> getConnections() {
		return connections;
	}

	public void setConnections(Vector<CustomisedConnection> connections) {
		this.connections = connections;
	}
	 
	public MyCustomisedPool(DBConfig conf) {
		this.conf = conf;
	}

	
	
	
	
	
	//test 
	public static void main(String[] args) throws SQLException, InstantiationException, IllegalAccessException, ClassNotFoundException {
		MyCustomisedPool pool = new MyCustomisedPool(new DBConfig() );
		pool.initConnection(); 
		for (int i = 0; i < 1000; i++) {
			CustomisedConnection connection = pool.getConnection();
			System.out.println(pool.getPoolSize());
			try{
				pool.testConnection(connection.getConnection());
			}catch(Exception e){
				e.printStackTrace();
				pool.closeConnection(connection.getConnection());
			}finally{
				pool.returnConnection(connection.getConnection());
			}
		}
	}
	
}

 

 

 

 

 

 

 

 

 

 

 

 

捐助开发者 

在兴趣的驱动下,写一个免费的东西,有欣喜,也还有汗水,希望你喜欢我的作品,同时也能支持一下。 当然,有钱捧个钱场(支持支付宝和微信 以及扣扣群),没钱捧个人场,谢谢各位。

 

个人主页http://knight-black-bob.iteye.com/


手写 基础 数据库连接池
            
    
    博客分类: java 手写基础数据库连接池java 手写 基础 数据库连接池
            
    
    博客分类: java 手写基础数据库连接池java 手写 基础 数据库连接池
            
    
    博客分类: java 手写基础数据库连接池java 
 
 
 谢谢您的赞助,我会做的更好!