`
knight_black_bob
  • 浏览: 822921 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

手写 基础 数据库连接池

    博客分类:
  • java
阅读更多

手写数据库连接池 基础

 

 

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/



 
 
 谢谢您的赞助,我会做的更好!

0
0
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics