因為工作需要要使用到連接池
目的
消除數據庫頻繁連接帶來的開銷和瓶頸
解決方案
不過多的限制用戶的使用
盡量保持用戶的習慣
目前的很多方法都是要求用戶只能按規定方法使用連接
能維護連接的正常狀態
因為針對數據庫連接創建的資源
//判斷是使用了createStatement語句 if (CREATESTATE
//判斷是否調用了close的方法
正確保護類不被違例使用
一個考慮就是不能讓用戶隨便使用代理類
/** * 創建連接的工廠
提供良好的用戶接口
使用靜態方法創建工廠
ConnectionParam param = new ConnectionParam(driver
為了實現連接池的正常運作
/** * 使用指定的參數創建一個連接池 */ public ConnectionFactory(ConnectionParam param
連接池的管理
對於連接池的管理,我是設想使用靜態管理和動態管理兩種策略,設置了最大限制,和恆定的連接數。tW.wingwiT.COM使用了2個池,一個空閒池,一個使用池。靜態就是使用的時候發現空閒連接不夠再去檢查。動態就是使用了一個線程定時檢查。
//根據策略判斷是否需要查詢 if (m_instance.ManageType != 0) { Thread t = new Thread(new FactoryMangeThread(m_instance)); t.start(); }
//連接池調度線程public class FactoryMangeThread implements Runnable { ConnectionFactory cf = null; long delay = 1000; public FactoryMangeThread(ConnectionFactory obj) { cf = obj; } /* (non-Javadoc) * @see java.lang.Runnable#run() */ public void run() { while(true){ try{ Thread.sleep(delay); } catch(InterruptedException e){} System.out.println("eeeee"); //判斷是否已經關閉了工廠,那就退出監聽 if (cf.isCreate()) cf.schedule(); else System.exit(1); } }}
最後給出完整的源代碼:
--------------------------------------------------------------------------------
_Connectio.java
package nnectionpool;
import java.lang.reflect.*;import java.sql.*;
/** * @author youyongming * 定義數據庫連接的代理類 */public class _Connection implements InvocationHandler { //定義連接 private Connection conn = null; //定義監控連接創建的語句 private Statement statRef = null; private PreparedStatement prestatRef = null; //是否支持事務標志 private boolean supportTransaction = false; //數據庫的忙狀態 private boolean isFree = false; //最後一次訪問時間 long lastAccessTime = 0; //定義要接管的函數的名字 String CREATESTATE = "createStatement"; String CLOSE = "close"; String PREPARESTATEMENT = "prepareStatement"; String COMMIT = "commit"; String ROLLBACK = "rollback";
/** * 構造函數,采用私有,防止被直接創建 * @param param 連接參數 */ private _Connection(ConnectionParam param) { //記錄日至 try{ //創建連接 Class.forName(param.getDriver()).newInstance(); conn = DriverManager.getConnection(param.getUrl(),param.getUser(), param.getPassword()); DatabaseMetaData dm = null; dm = conn.getMetaData(); //判斷是否支持事務 supportTransaction = dm.supportsTransactions(); } catch(Exception e) { e.printStackTrace(); } }
/* (non-Javadoc) * @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[]) */ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object obj = null; //判斷是否調用了close的方法,如果調用close方法則把連接置為無用狀態 if(CLOSE.equals(method.getName())) { //設置不使用標志 setIsFree(false); //檢查是否有後續工作,清除該連接無用資源 if (statRef != null) statRef.close(); if (prestatRef != null) prestatRef.close(); return null; } //判斷是使用了createStatement語句 if (CREATESTATE.equals(method.getName())) { obj = method.invoke(conn, args); statRef = (Statement)obj;//記錄語句 return obj; } //判斷是使用了prepareStatement語句 if (PREPARESTATEMENT.equals(method.getName())) { obj = method.invoke(conn, args); prestatRef = (PreparedStatement)obj; return obj; } //如果不支持事務,就不執行該事物的代碼 if ((COMMIT.equals(method.getName())||ROLLBACK.equals(method.getName())) && (!isSupportTransaction())) return null; obj = method.invoke(conn, args); //設置最後一次訪問時間,以便及時清除超時的連接 lastAccessTime = System.currentTimeMillis(); return obj; }
/** * 創建連接的工廠,只能讓工廠調用 * @param factory 要調用工廠,並且一定被正確初始化 * @param param 連接參數 * @return 連接 */ static public _Connection getConnection(Connec
From:http://tw.wingwit.com/Article/program/Java/hx/201311/26787.html