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