package scut.ailab.connectionpool; import java.lang.reflect.*; import java.sql.*; /** * @author youyongming * 定義數據庫連接的代理類(lèi) */ public class _Connection implements InvocationHandler { //定義連接 private Connection conn = null; //定義監控連接創(chuàng )建的語(yǔ)句 private Statement statRef = null; private PreparedStatement prestatRef = null; //是否支持事務(wù)標志 private boolean supportTransaction = false; //數據庫的忙狀態(tài) private boolean isFree = false; //最后一次訪(fǎng)問(wèn)時(shí)間 long lastAccessTime = 0; //定義要接管的函數的名字 String CREATESTATE = "createStatement"; String CLOSE = "close"; String PREPARESTATEMENT = "prepareStatement"; String COMMIT = "commit"; String ROLLBACK = "rollback"; /** * 構造函數,采用私有,防止被直接創(chuàng )建 * @param param 連接參數 */ private _Connection(ConnectionParam param) { //記錄日至 try{ //創(chuàng )建連接 Class.forName(param.getDriver()).newInstance(); conn = DriverManager.getConnection(param.getUrl(),param.getUser(), param.getPassword()); DatabaseMetaData dm = null; dm = conn.getMetaData(); //判斷是否支持事務(wù) 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方法則把連接置為無(wú)用狀態(tài) if(CLOSE.equals(method.getName())) { //設置不使用標志 setIsFree(false); //檢查是否有后續工作,清除該連接無(wú)用資源 if (statRef != null) statRef.close(); if (prestatRef != null) prestatRef.close(); return null; } //判斷是使用了createStatement語(yǔ)句 if (CREATESTATE.equals(method.getName())) { obj = method.invoke(conn, args); statRef = (Statement)obj;//記錄語(yǔ)句 return obj; } //判斷是使用了prepareStatement語(yǔ)句 if (PREPARESTATEMENT.equals(method.getName())) { obj = method.invoke(conn, args); prestatRef = (PreparedStatement)obj; return obj; } //如果不支持事務(wù),就不執行該事物的代碼 if ((COMMIT.equals(method.getName())||ROLLBACK.equals(method.getName())) && (!isSupportTransaction())) return null; obj = method.invoke(conn, args); //設置最后一次訪(fǎng)問(wèn)時(shí)間,以便及時(shí)清除超時(shí)的連接 lastAccessTime = System.currentTimeMillis(); return obj; } /** * 創(chuàng )建連接的工廠(chǎng),只能讓工廠(chǎng)調用 * @param factory 要調用工廠(chǎng),并且一定被正確初始化 * @param param 連接參數 * @return 連接 */ static public _Connection getConnection(ConnectionFactory factory, ConnectionParam param) { if (factory.isCreate())//判斷是否正確初始化的工廠(chǎng) { _Connection _conn = new _Connection(param); return _conn; } else return null; } public Connection getFreeConnection() { //返回數據庫連接conn的接管類(lèi),以便截住close方法 Connection conn2 = (Connection)Proxy.newProxyInstance( conn.getClass().getClassLoader(), conn.getClass().getInterfaces(),this); return conn2; } /** * 該方法真正的關(guān)閉了數據庫的連接 * @throws SQLException */ void close() throws SQLException{ //由于類(lèi)屬性conn是沒(méi)有被接管的連接,因此一旦調用close方法后就直接關(guān)閉連接 conn.close(); } public void setIsFree(boolean value) { isFree = value; } public boolean isFree() { return isFree; } /** * 判斷是否支持事務(wù) * @return boolean */ public boolean isSupportTransaction() { return supportTransaction; } }
|