使用动态代理创建数据库连接池

1.首先创建一个连接池javabean实体模型

package com.test.createPool;

import java.io.FileNotFoundException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import com.sun.corba.se.impl.orbutil.threadpool.TimeoutException;

public class MyPool {
	
    private String driverClassName;
    private String url;
    private String username;
    private String password;
    
    private int maxActive;            //连接池中最大活跃数
    private int maxIdle;              //连接池的最大保存数
    private long maxWait;             //连接池的最长等待时间
    
    private static int active = 0;
    private static int idle = 0;
    private static int wait = 0;
    
    private static String key = "";   //将操作连接池获取连接操作时用来锁定的标识
   

	private static Set<Connection> set = new 	HashSet<Connection>();

    //定义一个获取连接的方法
    public Connection getConnection() throws SQLException, ClassNotFoundException{
    	
    	synchronized (key) {
			
    		//如果当前活动数小雨最大连接数
    		if(active<=maxActive){
    			
    			//如果当前活动数等于最大连接数,则进入等待
    			if(active==maxActive){
    				
    				try {
    					key.wait();
    					System.out.println("into wait!");
						throw new TimeoutException();
					} catch (TimeoutException e) {
						e.printStackTrace();
						return null;
					}catch (InterruptedException e) {
						e.printStackTrace();
					}
    			}
    		}
    		
    		//如果不等于最大连接数,则从连接对象集合中获取连接对象
    		if(!set.isEmpty()){
    			
    			Iterator<Connection> iterator = set.iterator();
    			Connection conn = iterator.next();
    			set.remove(conn);
    			active++;
    			return conn;
    		}
    		
    		MyInvocationHander invocationHander = new MyInvocationHander();
    		//如果连接池中没有连接对象,则创建连接加入到连接池中
    		Class.forName(driverClassName);
    		Connection conn = DriverManager.getConnection(url, username, password);
    		active++;
    		return invocationHander.bind(conn, maxIdle);
		}
    }
    
    
	public String getDriverClassName() {
		return driverClassName;
	}

	public void setDriverClassName(String driverClassName) {
		this.driverClassName = driverClassName;
	}

	public String getUrl() {
		return url;
	}

	public void setUrl(String url) {
		this.url = url;
	}

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public int getMaxActive() {
		return maxActive;
	}

	public void setMaxActive(int maxActive) {
		this.maxActive = maxActive;
	}

	public int getMaxIdle() {
		return maxIdle;
	}

	public void setMaxIdle(int maxIdle) {
		this.maxIdle = maxIdle;
	}

	public long getMaxWait() {
		return maxWait;
	}

	public void setMaxWait(long maxWait) {
		this.maxWait = maxWait;
	}
	 
    public static String getKey() {
		return key;
	}


	public static void setKey(String key) {
		MyPool.key = key;
	}
	public static int getActive() {
		return active;
	}
	public static void setActive(int active) {
		MyPool.active = active;
	}


	public static int getIdle() {
		return idle;
	}


	public static void setIdle(int idle) {
		MyPool.idle = idle;
	}


	public static int getWait() {
		return wait;
	}


	public static void setWait(int wait) {
		MyPool.wait = wait;
	}


	public static Set<Connection> getSet() {
		return MyPool.set;
	}

	public static void setSet(Set<Connection> set) {
		MyPool.set = set;
	} 
}

2.对用户关闭数据库连接进行判断,如果连接池中连接对象已满,则关闭相应的数据库连接对象

package com.test.createPool;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.Connection;
import java.util.Set;

public class MyInvocationHander implements InvocationHandler {

	private Object conn;
	private int maxIdle;
	private Set<Connection> set = MyPool.getSet();
	private String key = MyPool.getKey();
	
	public MyInvocationHander() {
		super();
	}
	
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		
		if(method.getName().equals("close")){
			Object result = null;
			synchronized (key) {
				if(set.size()<maxIdle){
					set.add((Connection)proxy);
				}else{
					if(conn!=null){
						result = method.invoke(conn, args);
					}
				}
				
				int active = MyPool.getActive();
				active--;
				MyPool.setActive(active);
				key.notify();
				return result;
			}
		}else{
			Object result = method.invoke(conn, args);
			return result;
		}
	}
	
	//绑定连接对象
	public Connection bind(Connection conn,int maxIdle){
		
		this.conn = conn;
		this.maxIdle = maxIdle;
		
		return (Connection)Proxy.newProxyInstance
				(conn.getClass().getClassLoader(), new Class[]{Connection.class}, this);
	}

}


3.对数据库连接池进行测试!


 

package com.test.createPool;

import java.sql.Connection;
import java.sql.SQLException;

public class TestPool {

 public static void main(String[] args) {
  
  MyPool pool = new MyPool();
  
  pool.setDriverClassName("com.mysql.jdbc.Driver");
  pool.setUrl("jdbc:mysql://localhost:3306/bbs");
  pool.setUsername("root");
  pool.setPassword("admin");
  
  pool.setMaxActive(4);
  pool.setMaxIdle(4);
  pool.setMaxWait(1000);
  
  try {
   Connection conn1 = pool.getConnection();
   System.out.println("conn1-->"+conn1);
   Connection conn2 = pool.getConnection();
   System.out.println("conn2-->"+conn2);
   Connection conn3 = pool.getConnection();
   System.out.println("conn3-->"+conn3);
   Connection conn4 = pool.getConnection();
   System.out.println("conn4-->"+conn4);
   System.out.println();
   
   conn1.close();
   conn2.close();
   conn3.close();
   conn4.close();
   
   Connection conn5 = pool.getConnection();
   System.out.println("conn5-->"+conn5);
   Connection conn6 = pool.getConnection();
   System.out.println("conn6-->"+conn6);
   Connection conn7 = pool.getConnection();
   System.out.println("conn7-->"+conn7);
   Connection conn8 = pool.getConnection();
   System.out.println("conn8-->"+conn8);
   
  } catch (ClassNotFoundException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (SQLException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
  
  
  
 }
}


 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值