通常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等。