JDBC 數據庫連接池

通常java應用程序在訪問數據庫時,直接創建一個數據庫連接,使用完畢後釋放連接。

如圖:

當數據庫連接量小的時候這樣做並無不妥,但若在訪問量大的時候就顯得低效了,如某網站一天訪問量在1000萬次,那麼在這一天web應用程序與數據庫就要進行等量的

連接和斷開操作。

 

爲了解決這個問題,引入了數據庫連接池技術(個人認爲數據庫連接池技術是爲解決這個問題的),它是批量創建一批數據庫連接,放到一個數據庫連接池,在需要數據庫連接時,

就像這個池子拿,用完後則將數據庫連接還回池子,數據庫連接的維護由池負責維護,這樣不管訪問量如何大,程序與數據庫的連接是不變的,不過當數據庫連接池的連接已用完,這時又有新的連接請求,此時池中已無連接,那麼就只能等待或返回異常,所以數據庫連接池一次批量創建的連接數量應根據實際情況來設置。

採用數據庫連接池技術如圖:

 

根據數據庫連接池工作原理來手動寫一個數據庫連接池,實現基本功能。

 

1.從池中拿出數據庫連接

2.用完後還回池裏

3.數據庫連接的存放與維護

 

 Code

 

 

package xgn.jdbc;

import java.io.InputStream;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.Connection;
import java.sql.DriverManager;
import java.util.LinkedList;
import java.util.Properties;

/***
 * 數據庫連接池實現類
 * @author dream
 *
 */
public class JDBCPool {
	//存放連接的集合
	private static LinkedList<Connection> dblist=new LinkedList<Connection>();
	//連接池容量
	private static final int number=100;
	static{
		try{
			Properties config=new Properties();
			InputStream in= JDBCPool.class.getClassLoader().getResourceAsStream("config.properties");
			config.load(in);
			for(int i=0;i<number;i++){
				Connection cn= DriverManager.getConnection(config.getProperty("Connstr"),config.getProperty("user"),config.getProperty("pwd"));
				ConnectionProxy conn=new ConnectionProxy(cn);
				Connection proxycn=conn.getConnectionProxy(cn,new Class[]{Connection.class},conn);
				dblist.addFirst(proxycn);
			}	
		}catch(Exception ex){
			throw new RuntimeException(ex);
		}
	}
	public static void recoverConnection(Connection cn){
		dblist.addFirst(cn);
	}
	public static Connection getConnection(){
		if(dblist.size()<=0){
			throw new RuntimeException("數據庫連接池無數據庫連接!");
		}
		return dblist.removeFirst();
	}
	public static int getConnectionNumber(){
		return dblist.size();
	}
	
	/***
	 * 數據庫連接代理類
	 * @author dream
	 *
	 */
	public static class ConnectionProxy implements InvocationHandler {
		private Object obj=null;
		private Object proxyobj=null;
		@Override
		public Object invoke(Object arg0, Method arg1, Object[] arg2)throws Throwable {
			Object ret=null;//方法返回值
			if(arg1.getName()=="close"){
				System.out.println("close");
				JDBCPool.recoverConnection((Connection)this.proxyobj);
				return ret;
			}
			ret=arg1.invoke(this.obj, arg2);
			return ret;
		}
		public ConnectionProxy(Connection cn){
			this.obj=cn;
		}
		
		public Connection getConnectionProxy(Connection cn,Class[] cls,InvocationHandler h){
			this.proxyobj= Proxy.newProxyInstance(cn.getClass().getClassLoader(),cls,h);
			return (Connection)this.proxyobj;
		}
		
	}
}


常用的數據庫連接池有:DBCP、tomcat 的數據庫連接池(內部也是DBCP)、C3P0等。

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章