java 數(shù)據(jù)庫連接池 的 實現(xiàn)代碼

- package ?com.xiaobian; ??
- ??
- /** ?
- ?*? 數(shù)據(jù)庫連接池 管理類 ?
- ?*/ ??
- import ?java.io.*; ??
- import ?java.sql.*; ??
- import ?java.util.*; ??
- import ?java.util.Date; ??
- ??
- /** ?
- ?*?管理類DBConnectionManager支持對一個或多個由屬性文件定義的 數(shù)據(jù)庫連接池 的 ?
- ?*?訪問.客戶程序可以調(diào)用getInstance()方法訪問本類的唯一實例 ?
- ?*/ ??
- public ? class ?DBConnectionManager?{ ??
- ???? ??
- ???? public ? static ? void ?main(String[]?args)?{ ??
- ????????DBConnectionManager?connectionManager?=?DBConnectionManager.getInstance(); ??
- ???????? ??
- ????????Connection?conn?=??connectionManager.getConnection( "idb" ); ??
- ???????????? try ?{ ??
- ????????????????Thread.sleep( 10 ); ??
- ????????????}? catch ?(InterruptedException?e)?{ ??
- ???????????????? //?TODO?Auto-generated?catch?block ??
- ????????????????e.printStackTrace(); ??
- ????????????} ??
- ????????Connection?conn1?=??connectionManager.getConnection( "idb" ); ??
- ????????Connection?conn2?=??connectionManager.getConnection( "idb" ); ??
- ????????Connection?conn3?=??connectionManager.getConnection( "idb" ); ??
- ????????Connection?conn4?=??connectionManager.getConnection( "idb" ); ??
- ????????Connection?conn5?=??connectionManager.getConnection( "idb" ); ??
- ????????connectionManager.freeConnection( "idb" ,?conn); ??
- ????????connectionManager.freeConnection( "idb" ,?conn1); ??
- ????????connectionManager.freeConnection( "idb" ,?conn2); ??
- ????????connectionManager.freeConnection( "idb" ,?conn3); ??
- ????????connectionManager.freeConnection( "idb" ,?conn4); ??
- ????????connectionManager.freeConnection( "idb" ,?conn5); ??
- ????????Connection?conn6?=?connectionManager.getConnection( "idb" ); ??
- ????????Connection?conn7?=?connectionManager.getConnection( "idb" ); ??
- ????????System.out.println( "?conn6?==?" +conn6?+ "?conn7?==?" +conn7); ??
- ???????? ??
- ????} ??
- ??
- ???? ??
- ???? static ? private ?DBConnectionManager?instance;? //?唯一實例 ??
- ??
- ???? static ? private ? int ?clients;? // ??
- ??
- ???? private ?Vector?drivers?=? new ?Vector(); ??
- ??
- ???? private ?PrintWriter?log; ??
- ??
- ???? private ?Hashtable?pools?=? new ?Hashtable(); ??
- ??
- ???? /** ?
- ?????*?返回唯一實例.如果是第一次調(diào)用此方法,則創(chuàng)建實例 ?
- ?????*? ?
- ?????*?@return?DBConnectionManager?唯一實例 ?
- ?????*/ ??
- ???? static ? synchronized ? public ?DBConnectionManager?getInstance()?{ ??
- ???????? if ?(instance?==? null )?{ ??
- ????????????instance?=? new ?DBConnectionManager(); ??
- ????????} ??
- ????????clients++; ??
- ???????? return ?instance; ??
- ????} ??
- ??
- ???? /** ?
- ?????*?建構(gòu)私有函數(shù)以防止其它對象創(chuàng)建本類實例 ?
- ?????*/ ??
- ???? private ?DBConnectionManager()?{ ??
- ????????init(); ??
- ????} ??
- ??
- ???? /** ?
- ?????*?將連接對象返回給由名字指定的連接池 ?
- ?????*? ?
- ?????*?@param?name ?
- ?????*????????????在屬性文件中定義的連接池名字 ?
- ?????*?@param?con ?
- ?????*????????????連接對象 ?
- ?????*/ ??
- ???? public ? void ?freeConnection(String?name,?Connection?con)?{ ??
- ????????DBConnectionPool?pool?=?(DBConnectionPool)?pools.get(name); ??
- ???????? if ?(pool?!=? null )?{ ??
- ????????????pool.freeConnection(con); ??
- ????????} ??
- ????} ??
- ??
- ???? /** ?
- ?????*?獲得一個可用的(空閑的)連接.如果沒有可用連接,且已有連接數(shù)小于最大連接數(shù)?限制,則創(chuàng)建并返回新連接 ?
- ?????*? ?
- ?????*?@param?name ?
- ?????*????????????在屬性文件中定義的連接池名字 ?
- ?????*?@return?Connection?可用連接或null ?
- ?????*/ ??
- ???? public ?Connection?getConnection(String?name)?{ ??
- ????????DBConnectionPool?pool?=?(DBConnectionPool)?pools.get(name); ??
- ???????? //System.out.println("?pool?==?"+pool); ??
- ???????? if ?(pool?!=? null )?{ ??
- ???????????? return ?pool.getConnection(); ??
- ????????} ??
- ???????? return ? null ; ??
- ????} ??
- ??
- ???? /** ?
- ?????*?獲得一個可用連接.若沒有可用連接,且已有連接數(shù)小于最大連接數(shù)限制,?則創(chuàng)建并返回新連接.否則,在指定的時間內(nèi)等待其它線程釋放連接. ?
- ?????*? ?
- ?????*?@param?name ?
- ?????*????????????連接池名字 ?
- ?????*?@param?time ?
- ?????*????????????以毫秒計的等待時間 ?
- ?????*?@return?Connection?可用連接或null ?
- ?????*/ ??
- ???? public ?Connection?getConnection(String?name,? long ?time)?{ ??
- ????????DBConnectionPool?pool?=?(DBConnectionPool)?pools.get(name); ??
- ???????? if ?(pool?!=? null )?{ ??
- ???????????? return ?pool.getConnection(time); ??
- ????????} ??
- ???????? return ? null ; ??
- ????} ??
- ??
- ???? /** ?
- ?????*?關(guān)閉所有連接,撤銷驅(qū)動程序的注冊 ?
- ?????*/ ??
- ???? public ? synchronized ? void ?release()?{ ??
- ???????? //?等待直到最后一個客戶程序調(diào)用 ??
- ???????? if ?(--clients?!=? 0 )?{ ??
- ???????????? return ; ??
- ????????} ??
- ????????Enumeration?allPools?=?pools.elements(); ??
- ???????? while ?(allPools.hasMoreElements())?{ ??
- ????????????DBConnectionPool?pool?=?(DBConnectionPool)?allPools.nextElement(); ??
- ????????????pool.release(); ??
- ????????} ??
- ????????Enumeration?allDrivers?=?drivers.elements(); ??
- ???????? while ?(allDrivers.hasMoreElements())?{ ??
- ????????????Driver?driver?=?(Driver)?allDrivers.nextElement(); ??
- ???????????? try ?{ ??
- ????????????????DriverManager.deregisterDriver(driver); ??
- ????????????????log( "撤銷JDBC驅(qū)動程序?" ?+?driver.getClass().getName()?+? "的注冊" ); ??
- ????????????}? catch ?(SQLException?e)?{ ??
- ????????????????log(e,? "無法撤銷下列JDBC驅(qū)動程序的注冊:?" ?+?driver.getClass().getName()); ??
- ????????????} ??
- ????????} ??
- ????} ??
- ??
- ???? /** ?
- ?????*?根據(jù)指定屬性創(chuàng)建連接池實例. ?
- ?????*? ?
- ?????*?@param?props ?
- ?????*????????????連接池屬性 ?
- ?????*/ ??
- ???? private ? void ?createPools(Properties?props)?{ ??
- ????????Enumeration?propNames?=?props.propertyNames(); ??
- ???????? while ?(propNames.hasMoreElements())?{ ??
- ????????????String?name?=?(String)?propNames.nextElement(); ??
- ???????????? if ?(name.endsWith( ".url" ))?{ ??
- ????????????????String?poolName?=?name.substring( 0 ,?name.lastIndexOf( "." )); ??
- ???????????????? //System.out.println("?poolName?||"+poolName+"|"); ??
- ????????????????String?url?=?props.getProperty(poolName?+? ".url" ); ??
- ???????????????? if ?(url?==? null )?{ ??
- ????????????????????log( "沒有為連接池" ?+?poolName?+? "指定URL" ); ??
- ???????????????????? continue ; ??
- ????????????????} ??
- ????????????????String?user?=?props.getProperty(poolName?+? ".user" ); ??
- ????????????????String?password?=?props.getProperty(poolName?+? ".password" ); ??
- ????????????????String?maxconn?=?props.getProperty(poolName?+? ".maxconn" ,? "0" ); ??
- ???????????????? int ?max; ??
- ???????????????? try ?{ ??
- ????????????????????max?=?Integer.valueOf(maxconn).intValue(); ??
- ????????????????}? catch ?(NumberFormatException?e)?{ ??
- ????????????????????log( "錯誤的最大連接數(shù)限制:?" ?+?maxconn?+? "?.連接池:?" ?+?poolName); ??
- ????????????????????max?=? 0 ; ??
- ????????????????} ??
- ????????????????DBConnectionPool?pool?=? new ?DBConnectionPool(poolName,?url, ??
- ????????????????????????user,?password,?max); ??
- ????????????????pools.put(poolName,?pool); ??
- ????????????????log( "成功創(chuàng)建連接池" ?+?poolName); ??
- ????????????} ??
- ????????} ??
- ????} ??
- ??
- ???? //?-------------------------------------------------------------------------------- ??
- ??
- ???? /** ?
- ?????*?讀取屬性完成初始化 ?
- ?????*/ ??
- ???? private ? void ?init()?{ ??
- ???????? ??
- ????????InputStream?fileinputstream?=? null ; ??
- ???????? try ?{ ??
- ????????????fileinputstream?=? new ?FileInputStream( "./src/db.properties" ); ??
- ????????}? catch ?(FileNotFoundException?e1)?{ ??
- ????????????e1.printStackTrace(); ??
- ????????} ??
- ???????? //BufferedReader?bufferedreader?=?new?BufferedReader(new?InputStreamReader(fileinputstream)); ??
- ??
- ???????? //InputStream?is?=?getClass().getResourceAsStream("D:/workspace/UmessageSms/src/db.properties"); ??
- ????????Properties?dbProps?=? new ?Properties(); ??
- ???????? try ?{ ??
- ????????????dbProps.load(fileinputstream); ??
- ????????}? catch ?(Exception?e)?{ ??
- ????????????e.printStackTrace(); ??
- ????????????System.err.println( "不能讀取屬性文件.?" ??
- ????????????????????+? "請確保db.properties在CLASSPATH指定的路徑中" ); ??
- ???????????? return ; ??
- ????????} ??
- ????????String?logFile?=?dbProps.getProperty( "logfile" , ??
- ???????????????? "DBConnectionManager.log" ); ??
- ???????? ??
- ???????? //System.out.println(dbProps.getProperty("logfile")); ??
- ???????? try ?{ ??
- ????????????log?=? new ?PrintWriter( new ?FileWriter(logFile,? true ),? true ); ??
- ????????}? catch ?(IOException?e)?{ ??
- ????????????System.err.println( "無法打開日志文件:?" ?+?logFile); ??
- ????????????log?=? new ?PrintWriter(System.err); ??
- ????????} ??
- ????????loadDrivers(dbProps); ??
- ????????createPools(dbProps); ??
- ????} ??
- ??
- ???? /** ?
- ?????*?裝載和注冊所有JDBC驅(qū)動程序 ?
- ?????*? ?
- ?????*?@param?props ?
- ?????*????????????屬性 ?
- ?????*/ ??
- ???? private ? void ?loadDrivers(Properties?props)?{ ??
- ????????String?driverClasses?=?props.getProperty( "drivers" ); ??
- ????????StringTokenizer?st?=? new ?StringTokenizer(driverClasses); ??
- ???????? while ?(st.hasMoreElements())?{ ??
- ????????????String?driverClassName?=?st.nextToken().trim(); ??
- ???????????? try ?{ ??
- ????????????????Driver?driver?=?(Driver)?Class.forName(driverClassName) ??
- ????????????????????????.newInstance(); ??
- ????????????????DriverManager.registerDriver(driver); ??
- ????????????????drivers.addElement(driver); ??
- ????????????????log( "成功注冊JDBC驅(qū)動程序" ?+?driverClassName); ??
- ????????????}? catch ?(Exception?e)?{ ??
- ????????????????log( "無法注冊JDBC驅(qū)動程序:?" ?+?driverClassName?+? ",?錯誤:?" ?+?e); ??
- ????????????} ??
- ????????} ??
- ????} ??
- ??
- ???? /** ?
- ?????*?將文本信息寫入日志文件 ?
- ?????*/ ??
- ???? private ? void ?log(String?msg)?{ ??
- ????????log.println( new ?Date()?+? ":?" ?+?msg); ??
- ????} ??
- ??
- ???? /** ?
- ?????*?將文本信息與異常寫入日志文件 ?
- ?????*/ ??
- ???? private ? void ?log(Throwable?e,?String?msg)?{ ??
- ????????log.println( new ?Date()?+? ":?" ?+?msg); ??
- ????????e.printStackTrace(log); ??
- ????} ??
- ??
- ???? /**?*************************************************************?*/ ??
- ???? /**?********************內(nèi)部類DBConnectionPool********************?*/ ??
- ???? /**?*************************************************************?*/ ??
- ???? /** ?
- ?????*?此內(nèi)部類定義了一個連接池.它能夠根據(jù)要求創(chuàng)建新連接,直到預(yù)定的最?大連接數(shù)為止.在返回連接給客戶程序之前,它能夠驗證連接的有效性. ?
- ?????*/ ??
- ???? class ?DBConnectionPool?{ ??
- ???????? private ? int ?checkedOut;? //?當前連接數(shù) ??
- ??
- ???????? private ?Vector?freeConnections?=? new ?Vector();? //?保存所有可用連接 ??
- ??
- ???????? private ? int ?maxConn;? //?此連接池允許建立的最大連接數(shù) ??
- ??
- ???????? private ?String?name;? //?連接池名字 ??
- ??
- ???????? private ?String?password;? //?密碼或null ??
- ??
- ???????? private ?String?URL;? //?數(shù)據(jù)庫的JDBC?URL ??
- ??
- ???????? private ?String?user;? //?數(shù)據(jù)庫賬號或null ??
- ??
- ???????? /** ?
- ?????????*?創(chuàng)建新的連接池 ?
- ?????????*? ?
- ?????????*?@param?name ?
- ?????????*????????????連接池名字 ?
- ?????????*?@param?URL ?
- ?????????*????????????數(shù)據(jù)庫的JDBC?URL ?
- ?????????*?@param?user ?
- ?????????*????????????數(shù)據(jù)庫帳號或?null ?
- ?????????*?@param?password ?
- ?????????*????????????密碼或?null ?
- ?????????*?@param?maxConn ?
- ?????????*????????????此連接池允許建立的最大連接數(shù) ?
- ?????????*/ ??
- ???????? public ?DBConnectionPool(String?name,?String?URL,?String?user, ??
- ????????????????String?password,? int ?maxConn)?{ ??
- ???????????? this .name?=?name; ??
- ???????????? this .URL?=?URL; ??
- ???????????? this .user?=?user; ??
- ???????????? this .password?=?password; ??
- ???????????? this .maxConn?=?maxConn; ??
- ????????} ??
- ??
- ???????? /** ?
- ?????????*?將不再使用的連接返回給連接池 ?
- ?????????*? ?
- ?????????*?@param?con ?
- ?????????*????????????客戶程序釋放的連接 ?
- ?????????*/ ??
- ???????? public ? synchronized ? void ?freeConnection(Connection?con)?{ ??
- ???????????? //?將指定連接加入到向量末尾 ??
- ????????????freeConnections.addElement(con); ??
- ????????????checkedOut--; ??
- ????????????notifyAll();? //?刪除等待隊列中的所有線程 ??
- ????????} ??
- ??
- ???????? /** ?
- ?????????*?從連接池獲得一個可用連接.如果沒有空閑的連接且當前連接數(shù)小于最大連接 ?
- ?????????*?數(shù)限制,則創(chuàng)建新連接.如原來登記為可用的連接不再有效,則從向量刪除之,?然后遞歸調(diào)用自己以嘗試新的可用連接. ?
- ?????????*/ ??
- ???????? public ? synchronized ?Connection?getConnection()?{ ??
- ????????????Connection?con?=? null ; ??
- ???????????? //System.out.println("?freeConnections.size()?"+freeConnections.size()); ??
- ???????????? if ?(freeConnections.size()?>? 0 )?{ ??
- ???????????????? //?獲取向量中第一個可用連接 ??
- ????????????????con?=?(Connection)?freeConnections.firstElement(); ??
- ????????????????freeConnections.removeElementAt( 0 ); ??
- ???????????????? try ?{ ??
- ???????????????????? if ?(con.isClosed())?{ ??
- ????????????????????????log( "從連接池" ?+?name?+? "刪除一個無效連接" ); ??
- ???????????????????????? //?遞歸調(diào)用自己,嘗試再次獲取可用連接 ??
- ????????????????????????con?=?getConnection(); ??
- ????????????????????} ??
- ????????????????}? catch ?(SQLException?e)?{ ??
- ????????????????????log( "從連接池" ?+?name?+? "刪除一個無效連接" ); ??
- ???????????????????? //?遞歸調(diào)用自己,嘗試再次獲取可用連接 ??
- ????????????????????con?=?getConnection(); ??
- ????????????????} ??
- ????????????}? else ? if ?(maxConn?==? 0 ?||?checkedOut?<?maxConn)?{ ??
- ????????????????con?=?newConnection(); ??
- ????????????} ??
- ???????????? if ?(con?!=? null )?{ ??
- ????????????????checkedOut++; ??
- ????????????} ??
- ????????????System.out.println( "con?==?" +con); ??
- ???????????? return ?con; ??
- ????????} ??
- ??
- ???????? /** ?
- ?????????*?從連接池獲取可用連接.可以指定客戶程序能夠等待的最長時間?參見前一個getConnection()方法. ?
- ?????????*? ?
- ?????????*?@param?timeout ?
- ?????????*????????????以毫秒計的等待時間限制 ?
- ?????????*/ ??
- ???????? public ? synchronized ?Connection?getConnection( long ?timeout)?{ ??
- ???????????? long ?startTime?=? new ?Date().getTime(); ??
- ????????????Connection?con; ??
- ???????????? while ?((con?=?getConnection())?==? null )?{ ??
- ???????????????? try ?{ ??
- ????????????????????wait(timeout); ??
- ????????????????}? catch ?(InterruptedException?e)?{ ??
- ????????????????} ??
- ???????????????? if ?(( new ?Date().getTime()?-?startTime)?>=?timeout)?{ ??
- ???????????????????? //?wait()返回的原因是超時 ??
- ???????????????????? return ? null ; ??
- ????????????????} ??
- ????????????} ??
- ???????????? return ?con; ??
- ????????} ??
- ??
- ???????? /** ?
- ?????????*?關(guān)閉所有連接 ?
- ?????????*/ ??
- ???????? public ? synchronized ? void ?release()?{ ??
- ????????????Enumeration?allConnections?=?freeConnections.elements(); ??
- ???????????? while ?(allConnections.hasMoreElements())?{ ??
- ????????????????Connection?con?=?(Connection)?allConnections.nextElement(); ??
- ???????????????? try ?{ ??
- ????????????????????con.close(); ??
- ????????????????????log( "關(guān)閉連接池" ?+?name?+? "中的一個連接" ); ??
- ????????????????}? catch ?(SQLException?e)?{ ??
- ????????????????????log(e,? "無法關(guān)閉連接池" ?+?name?+? "中的連接" ); ??
- ????????????????} ??
- ????????????} ??
- ????????????freeConnections.removeAllElements(); ??
- ????????} ??
- ??
- ???????? /** ?
- ?????????*?創(chuàng)建新的連接 ?
- ?????????*/ ??
- ???????? private ?Connection?newConnection()?{ ??
- ????????????Connection?con?=? null ; ??
- ???????????? try ?{ ??
- ???????????????? if ?(user?==? null )?{ ??
- ????????????????????con?=?DriverManager.getConnection(URL); ??
- ????????????????}? else ?{ ??
- ????????????????????con?=?DriverManager.getConnection(URL,?user,?password); ??
- ????????????????} ??
- ????????????????log( "連接池" ?+?name?+? "創(chuàng)建一個新的連接" ); ??
- ????????????}? catch ?(SQLException?e)?{ ??
- ????????????????log(e,? "無法創(chuàng)建下列URL的連接:?" ?+?URL); ??
- ???????????????? return ? null ; ??
- ????????????} ??
- ???????????? return ?con; ??
- ????????} ??
- ????} ??
- }??
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯(lián)系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
