posts - 22,comments - 35,trackbacks - 0
          ??1 package ?ConnectionPool;?
          ??2 /** ?
          ??3 此內部類定義了一個連接池。它能夠根據要求創建新連接,直到預定的最大連接數為止。在返回連接給客戶程序之前,它能夠?
          ??4 驗證連接的有效性。此類提供以下功能:?
          ??5 1.從連接池獲取(或創建)可用連接?
          ??6 2.把連接返回給連接池?
          ??7 3.在系統關閉時釋放所有資源,關閉所有連接?
          ??8 4.處理無效連接(原來登記為可用的連接,由于某種原因不再可用,如超時,通訊問題)?
          ??9 5.限制連接池中的連接總數不超過某個預定值?
          ?10 */
          ?
          ?11 import ?java.io. * ;?
          ?12 import ?java.sql. * ;?
          ?13 import ?java.util. * ;?
          ?14 import ?java.util.Date;?
          ?15
          ?16 class ?DBConnectionPool?
          ?17 {?
          ?18 ???? private ? int ?checkedOut;?
          ?19 ???? private ?PrintWriter?logPrint;?
          ?20 ???? private ?Vector?freeConnections? = ? new ?Vector();?
          ?21 ???? private ? int ?maxConn;?
          ?22 ???? private ?String?name;?
          ?23 ???? private ?String?password;?
          ?24 ???? private ?String?URL;?
          ?25 ???? private ?String?user;?
          ?26 ????
          ?27 ???? /** ?
          ?28 ????創建新的連接池?
          ?29 ????* @param ?name?連接池名字?
          ?30 ????* @param ?URL?數據庫的JDBC?URL?
          ?31 ????* @param ?user?數據庫帳號,或null?
          ?32 ????* @param ?password?密碼,或null?
          ?33 ????* @param ?maxConn?此連接池允許建立的最大連接數?
          ?34 ???? */
          ?
          ?35 ???? public ?DBConnectionPool(String?name,?String?URL,?String?user,?String?password,? int ?maxConn)? {?
          ?36 ???????? this .name? = ?name;?
          ?37 ???????? this .URL? = ?URL;?
          ?38 ???????? this .user? = ?user;?
          ?39 ???????? this .password? = ?password;?
          ?40 ???????? this .maxConn? = ?maxConn;?
          ?41 ????????InputStream?is? = ?getClass().getResourceAsStream( " /db.properties " );?
          ?42 ????????Properties?dbProps? = ? new ?Properties();?
          ?43 ???????? try ? {?
          ?44 ????????????dbProps.load(is);?
          ?45 ????????}
          ?
          ?46 ???????? catch (Exception?e)? {?
          ?47 ????????????System.err.println( " 不能讀取屬性文件. " ? + ? " 請確保db.properties在CLASSPATH指定的路徑中 " );?
          ?48 ???????????? return ;?
          ?49 ????????}
          ?
          ?50 ????????String?logFile? = ?dbProps.getProperty( " Poollogfile " ,? " DBConnectionPool.log " );?
          ?51 ???????? try ? {?
          ?52 ????????????logPrint? = ? new ?PrintWriter( new ?FileWriter(logFile,? true ),? true );?
          ?53 ????????}
          ?
          ?54 ???????? catch (IOException?e)? {?
          ?55 ????????????System.err.println( " 無法打開日志文件: " ? + ?logFile);?
          ?56 ????????????logPrint? = ? new ?PrintWriter(System.err);?
          ?57 ????????}
          ?
          ?58 ????}
          ?
          ?59 ????
          ?60 ????
          ?61 ???? /** ?
          ?62 ????將不再使用的連接返回給連接池?
          ?63 ????* @param ?con?客戶程序釋放的連接?
          ?64 ???? */
          ?
          ?65 ???? public ? synchronized ? void ?freeConnection(Connection?con)? {?
          ?66 ????????freeConnections.addElement(con);?
          ?67 ????????checkedOut -- ;?
          ?68 ????????notifyAll();?
          ?69 ????}
          ?
          ?70 ????
          ?71 ????
          ?72 ???? /** ?
          ?73 ????從連接池獲得一個可用連接,如沒有空閑的連接且當前連接數小于最大連接數,則創建新連接,?
          ?74 ????如原來登記為可用的連接不再有效,則從向量刪除之,然后遞歸調用自己以嘗試新的可用連接?
          ?75 ???? */
          ?
          ?76 ???? public ? synchronized ?Connection?getConnection()? {?
          ?77 ????????Connection?con? = ? null ;?
          ?78 ???????? if (freeConnections.size()? > ? 0 )? {?? // ?獲取向量中第一個可用連接?
          ?79 ????????????con? = ?(Connection)freeConnections.firstElement();?
          ?80 ????????????freeConnections.removeElementAt( 0 );?
          ?81 ???????????? try ? {?
          ?82 ???????????????? if (con.isClosed())? {?
          ?83 ????????????????????log( " 從連接池 " ? + ?name? + ? " 刪除一個無效連接 " );?
          ?84 ????????????????????con? = ?getConnection();?
          ?85 ????????????????}
          ?
          ?86 ????????????}
          ?
          ?87 ???????????? catch (SQLException?e)? {?
          ?88 ????????????????log( " 從連接池 " ? + ?name? + ? " 刪除一個無效連接 " );?
          ?89 ????????????????con? = ?getConnection();?
          ?90 ????????????}
          ?
          ?91 ????????}
          ?
          ?92 ???????? else ? if (maxConn? == ? 0 ? || ?checkedOut? < ?maxConn)? {?
          ?93 ????????????con? = ?newConnection();?
          ?94 ????????}
          ?
          ?95 ???????? if (con? != ? null )? {?
          ?96 ????????????checkedOut ++ ;?
          ?97 ????????}
          ?
          ?98 ???????? return ?con;?
          ?99 ????}
          ?
          100 ????
          101 ????
          102 ???? /** ?
          103 ????從連接池獲取可用連接,可以指定客戶程序能夠等待的最長時間?
          104 ????* @param ?timeout?以毫秒計的等待時間限制?
          105 ???? */
          ?
          106 ???? public ? synchronized ?Connection?getConnection( long ?timeout)? {?
          107 ???????? long ?startTime? = ? new ?Date().getTime();?
          108 ????????Connection?con;?
          109 ???????? while ((con? = ?getConnection())? == ? null )? {?
          110 ???????????? try ? {?
          111 ????????????????wait(timeout);?
          112 ????????????}
          ?
          113 ???????????? catch (InterruptedException?e) {} ?
          114 ????????????
          115 ???????????? if (( new ?Date().getTime()? - ?startTime)? >= ?timeout)? {?
          116 ???????????????? return ? null ;?
          117 ????????????}
          ?
          118 ????????}
          ?
          119 ???????? return ?con;?
          120 ????}
          ?
          121 ????
          122 ????
          123 ???? /** ?
          124 ????關閉所有連接?
          125 ???? */
          ?
          126 ???? public ? synchronized ? void ?release()? {?
          127 ????????Enumeration?allConnections? = ?freeConnections.elements();?
          128 ???????? while (allConnections.hasMoreElements())? {?
          129 ????????????Connection?con? = ?(Connection)allConnections.nextElement();?
          130 ???????????? try ? {?
          131 ????????????????con.close();?
          132 ????????????????log( " 關閉連接池 " ? + ?name? + ? " 中的一個連接 " );?
          133 ????????????}
          ?
          134 ???????????? catch (SQLException?e)? {?
          135 ????????????????log(e,? " 無法關閉連接池 " ? + ?name? + ? " 中的連接 " );?
          136 ????????????}
          ?
          137 ????????}
          ?
          138 ????????freeConnections.removeAllElements();?
          139 ????}
          ?
          140 ????
          141 ????
          142 ???? /** ?
          143 ????創建新的連接?
          144 ???? */
          ?
          145 ???? private ?Connection?newConnection()? {?
          146 ????????Connection?con? = ? null ;?
          147 ???????? try ? {?
          148 ???????????? if (user? == ? null )? {?
          149 ????????????????con? = ?DriverManager.getConnection(URL);?
          150 ????????????}
          ?
          151 ???????????? else ? {?
          152 ????????????????con? = ?DriverManager.getConnection(URL,?user,?password);?
          153 ????????????}
          ?
          154 ????????????log( " 連接池 " ? + ?name? + ? " 創建一個新的連接 " );?
          155 ????????}
          ?
          156 ???????? catch (SQLException?e)? {?
          157 ????????????log(e,? " 無法創建下列URL的連接 " ? + ?URL);?
          158 ???????????? return ? null ;?
          159 ????????}
          ?
          160 ???????? return ?con;?
          161 ????}
          ?
          162 ????
          163 ????
          164 ???? /** ?
          165 ????將文本信息寫入日志文件?
          166 ????缺省為packaged?
          167 ???? */
          ?
          168 ???? void ?log(String?msg)? {?
          169 ????????logPrint.println( new ?Date()? + ? " :? " ? + ?msg);?
          170 ????}
          ?
          171 ????
          172 ????
          173 ???? /** ?
          174 ????將文本信息與異常寫入日志文件?
          175 ???? */
          ?
          176 ???? void ?log(Throwable?e,?String?msg)? {?
          177 ????????logPrint.println( new ?Date()? + ? " :? " ? + ?msg);?
          178 ????????e.printStackTrace(logPrint);?
          179 ????}
          ?
          180 }
          ?


          ??1 package ?ConnectionPool;?
          ??2
          ??3 /* 此類用于管理多個連接池對象,它支持對一個或多個由屬性文件定義的數據庫連接池的訪問,客戶程序可以調用getInstance()方法訪問本類的唯一實例。它提供以下功能:?
          ??4 1.裝載和注冊JDBC驅動程序?
          ??5 2.根據在屬性文件中定義的屬性創建連接池對象?
          ??6 3.實現連接池名字與其實例之間的映射?
          ??7 4.跟蹤客戶程序對連接池的引用,保證在最后一個客戶程序結束時安全地關閉所有連接池?
          ??8 */
          ?
          ??9
          ?10 import ?java.io. * ;?
          ?11 import ?java.sql. * ;?
          ?12 import ?java.util. * ;?
          ?13 // import?com.supersoftintl.intranet.common.DBConnectionPool;?
          ?14 // import?java.util.Date;?
          ?15 /** ?
          ?16 *?管理類DBConnectionManager支持對一個或多個由屬性文件定義的數據庫連接?
          ?17 *?池的訪問.客戶程序可以調用getInstance()方法訪問本類的唯一實例.?
          ?18 */
          ?
          ?19 public ? class ?DBConnectionManager? {?
          ?20 ???? static ? private ?DBConnectionManager?instance; /* 唯一實例 */ ?
          ?21 ???? static ? private ? int ?clients;
          ?22 ????? /* 該計數代表引用DBConnectionManager唯一實例的客戶程序總數,?
          ?23 ????它將被用于控制連接池的關閉操作? */
          ?
          ?24 ????
          ?25 ???? static ? private ?String?DEFAULTCONNECTIONPOOL? = ? " ConnectionPool " ;?
          ?26 ???? private ?Vector?drivers? = ? new ?Vector();?
          ?27 ???? private ?PrintWriter?logPrint;?
          ?28 ???? private ?Hashtable?pools? = ? new ?Hashtable();?
          ?29 ????
          ?30 ???? /** ?
          ?31 ????返回唯一實例。如果是第一次調用此方法,則創建實例?
          ?32 ???? */
          ?
          ?33 ???? static ? synchronized ? public ?DBConnectionManager?getInstance()? {?
          ?34 ???????? if (instance? == ? null )? {?
          ?35 ????????????instance? = ? new ?DBConnectionManager();?
          ?36 ????????}
          ?
          ?37 ????????clients ++ ;?
          ?38 ???????? return ?instance;?
          ?39 ????}
          ?
          ?40 ????
          ?41 ????
          ?42 ???? /** ?
          ?43 ????建構函數私有以防止其它對象創建本類實例?
          ?44 ???? */
          ?
          ?45 ???? public ?DBConnectionManager()? {?
          ?46 ????????init();?
          ?47 ????}

          ?48 ????
          ?49 ????
          ?50 ???? /** ?Added?by?leo?on?2001-5-23?
          ?51 ????使用默認的連接池名,創建并返回新連接?
          ?52 ????*?
          ?53 ????*? @return ?Connection?可用連接或null?
          ?54 ???? */
          ?
          ?55 ???? public ?Connection?getConnection()? {?
          ?56 ???????? return ?getConnection(DEFAULTCONNECTIONPOOL);?
          ?57 ????}
          ?
          ?58 ????
          ?59 ????
          ?60 ???? /** ?
          ?61 ????獲得一個可用的(空閑的)連接.如果沒有可用連接,且已有連接數小于最大連接數?
          ?62 ????限制,則創建并返回新連接?
          ?63 ????*?
          ?64 ????*? @param ?name?在屬性文件中定義的連接池名字?
          ?65 ????*? @return ?Connection?可用連接或null?
          ?66 ???? */
          ?
          ?67 ???? public ?Connection?getConnection(String?name)? {?
          ?68 ????????DBConnectionPool?pool? = ?(DBConnectionPool)pools.get(name);?
          ?69 ???????? if (pool? != ? null )? {?
          ?70 ???????????? return ?pool.getConnection();?
          ?71 ????????}
          ?
          ?72 ???????? return ? null ;?
          ?73 ????}
          ?
          ?74 ????
          ?75 ????
          ?76 ???? /** ?
          ?77 ????獲得一個可用連接.若沒有可用連接,且已有連接數小于最大連接數限制,?
          ?78 ????則創建并返回新連接.否則,在指定的時間內等待其它線程釋放連接.?
          ?79 ????*?
          ?80 ????*? @param ?name?連接池名字?
          ?81 ????*? @param ?time?以毫秒計的等待時間?
          ?82 ????*? @return ?Connection?可用連接或null?
          ?83 ???? */
          ?
          ?84 ???? public ?Connection?getConnection(String?name,? long ?time)? {?
          ?85 ????????DBConnectionPool?pool? = ?(DBConnectionPool)pools.get(name);?
          ?86 ???????? if (pool? != ? null )? {?
          ?87 ???????????? return ?pool.getConnection(time);?
          ?88 ????????}
          ?
          ?89 ???????? return ? null ;?
          ?90 ????}
          ?
          ?91 ????
          ?92 ????
          ?93 ???? /** ?Added?by?leo?on?2001-5-23?
          ?94 ????將連接對象返回給默認的連接池?
          ?95 ????*?
          ?96 ????*? @param ?con?連接對象?
          ?97 ???? */
          ?
          ?98 ???? public ? void ?freeConnection(Connection?con)? {?
          ?99 ????????String?name? = ?DEFAULTCONNECTIONPOOL;?
          100 ????????freeConnection(name,con);?
          101 ????}
          ?
          102 ????
          103 ????
          104 ???? /** ?
          105 ????將連接對象返回給由名字指定的連接池?
          106 ????*?
          107 ????*? @param ?name?在屬性文件中定義的連接池名字?
          108 ????*? @param ?con?連接對象?
          109 ???? */
          ?
          110 ???? public ? void ?freeConnection(String?name,?Connection?con)? {?
          111 ????????DBConnectionPool?pool? = ?(DBConnectionPool)pools.get(name);?
          112 ???????? if (pool? != ? null )? {?
          113 ????????????pool.freeConnection(con);?
          114 ????????}
          ?
          115 ????}
          ?
          116 ????
          117 ????
          118 ???? /** ?
          119 ????關閉所有連接,撤銷驅動程序的注冊?
          120 ???? */
          ?
          121 ???? public ? synchronized ? void ?release()? {? // ?等待直到最后一個客戶程序調用?
          122 ???????? if ( -- clients? != ? 0 )? {?
          123 ???????????? return ;?
          124 ????????}
          ?
          125 ????????Enumeration?allPools? = ?pools.elements();?
          126 ???????? while (allPools.hasMoreElements())? {?
          127 ????????????DBConnectionPool?pool? = ?(DBConnectionPool)allPools.nextElement();?
          128 ????????????pool.release();?
          129 ????????}
          ?
          130 ????????Enumeration?allDrivers? = ?drivers.elements();?
          131 ???????? while (allDrivers.hasMoreElements())? {?
          132 ????????????Driver?driver? = ?(Driver)allDrivers.nextElement();?
          133 ???????????? try ? {?
          134 ????????????????DriverManager.deregisterDriver(driver);?
          135 ????????????????log( " 撤消JDBC驅動程序 " ? + ?driver.getClass().getName()? + ? " 的注冊 " );?
          136 ????????????}
          ?
          137 ???????????? catch (SQLException?e)? {?
          138 ????????????????log(e,? " 無法撤消下列JDBC驅動程序的注冊 " ? + ?driver.getClass().getName());?
          139 ????????????}
          ?
          140 ????????}
          ?
          141 ????}
          ?
          142 ????
          143 ????
          144 ???? /** ?
          145 ????根據指定屬性創建連接池實例.?
          146 ????*?
          147 ????*? @param ?props?連接池屬性?
          148 ???? */
          ?
          149 ???? private ? void ?createPools(Properties?props)? {?
          150 ????????Enumeration?propNames? = ?props.propertyNames();?
          151 ???????? while (propNames.hasMoreElements())? {?
          152 ????????????String?name? = ?(String)propNames.nextElement();?
          153 ???????????? if (name.endsWith( " .url " ))? {?
          154 ????????????????String?poolName? = ?name.substring( 0 ,?name.lastIndexOf( " . " ));?
          155 ????????????????String?url? = ?props.getProperty(poolName? + ? " .url " );?
          156 ???????????????? if (url? == ? null )? {?
          157 ????????????????????log( " 沒有為連接池 " ? + ?poolName? + ? " 指定URL " );?
          158 ???????????????????? continue ;?
          159 ????????????????}
          ?
          160 ????????????????String?user? = ?props.getProperty(poolName? + ? " .user " );?
          161 ????????????????String?password? = ?props.getProperty(poolName? + ? " .password " );?
          162 ????????????????String?maxconn? = ?props.getProperty(poolName? + ? " .maxconn " ,? " 0 " );?
          163 ???????????????? int ?max;?
          164 ???????????????? try ? {?
          165 ????????????????????max? = ?Integer.valueOf(maxconn).intvalue();?
          166 ????????????????}
          ?
          167 ???????????????? catch (NumberformatException?e)? {?
          168 ????????????????????log( " 錯誤的最大連接數限制: " ? + ?maxconn? + ? " .連接池: " ? + ?poolName);?
          169 ????????????????????log( " 自動改變設置為0--即無限制 " );?
          170 ????????????????????max? = ? 0 ;?
          171 ????????????????}
          ?
          172 ????????????????DBConnectionPool?pool? = ? new ?DBConnectionPool(poolName,?url,?user,?password,?max);?
          173 ????????????????pools.put(poolName,?pool);?
          174 ????????????????log( " 成功創建連接池 " ? + ?poolName);?
          175 ????????????}
          ?
          176 ????????}
          ?
          177 ????}
          ?
          178 ????
          179 ????
          180 ???? /** ?
          181 ????讀取屬性完成初始化?
          182 ???? */
          ?
          183 ???? private ? void ?init()? {?
          184 ????????InputStream?is? = ?getClass().getResourceAsStream( " /db.properties " );?
          185 ????????Properties?dbProps? = ? new ?Properties();?
          186 ???????? try ? {?
          187 ????????????dbProps.load(is);?
          188 ????????}
          ?
          189 ???????? catch (Exception?e)? {?
          190 ????????????System.err.println( " 不能讀取屬性文件. " ? + ? " 請確保db.properties在CLASSPATH指定的路徑中 " );?
          191 ???????????? return ;?
          192 ????????}
          ?
          193 ????????String?logFile? = ?dbProps.getProperty( " Managerlogfile " ,? " DBConnectionManager.log " );?
          194 ???????? try ? {?
          195 ????????????logPrint? = ? new ?PrintWriter( new ?FileWriter(logFile,? true ),? true );?
          196 ????????}
          ?
          197 ???????? catch (IOException?e)? {?
          198 ????????????System.err.println( " 無法打開日志文件: " ? + ?logFile);?
          199 ????????????logPrint? = ? new ?PrintWriter(System.err);?
          200 ????????}
          ?
          201 ????????loadDrivers(dbProps);?
          202 ????????createPools(dbProps);?
          203 ????}
          ?
          204 ????
          205 ????
          206 ???? /** ?
          207 ????裝載和注冊所有JDBC驅動程序?
          208 ????*?
          209 ????*? @param ?props?屬性?
          210 ???? */
          ?
          211 ???? private ? void ?loadDrivers(Properties?props)? {?
          212 ????????String?driverClasses? = ?props.getProperty( " drivers " );?
          213 ????????StringTokenizer?st? = ? new ?StringTokenizer(driverClasses);?
          214 ???????? while (st.hasMoreElements())? {?
          215 ????????????String?driverClassName? = ?st.nextToken().trim();?
          216 ???????????? try ? {?
          217 ????????????????Driver?driver? = ?(Driver)Class.forName(driverClassName).newInstance();?
          218 ????????????????DriverManager.registerDriver(driver);?
          219 ????????????????drivers.addElement(driver);?
          220 ????????????????log( " 成功JDBC注冊驅動程序 " ? + ?driverClassName);?
          221 ????????????}
          ?
          222 ???????????? catch (Exception?e)? {?
          223 ????????????????log( " 無法注冊JDBC驅動程序; " ? + ?driverClassName? + ? " ,錯誤: " ? + ?e);?
          224 ????????????}
          ?
          225 ????????}
          ?
          226 ????}
          ?
          227 ????
          228 ????
          229 ???? /** ?
          230 ????將文本信息寫入日志文件?
          231 ????缺省為packaged?
          232 ???? */
          ?
          233 ???? void ?log(String?msg)? {?
          234 ????????logPrint.println( new ?java.util.Date()? + ? " :? " ? + ?msg);?
          235 ????}
          ?
          236 ????
          237 ????
          238 ???? /** ?
          239 ????將文本信息與異常寫入日志文件?
          240 ???? */
          ?
          241 ???? void ?log(Throwable?e,?String?msg)? {?
          242 ????????logPrint.println( new ?java.util.Date()? + ? " :? " ? + ?msg);?
          243 ????????e.printStackTrace(logPrint);?
          244 ????}
          ?
          245 }
          ?
          posted on 2006-06-29 14:44 kelven 閱讀(2182) 評論(0)  編輯  收藏 所屬分類: java
          主站蜘蛛池模板: 承德县| 侯马市| 蒙阴县| 宜宾县| 柘荣县| 宁夏| 铅山县| 平安县| 额济纳旗| 抚州市| 尼木县| 紫阳县| 虹口区| 太原市| 绩溪县| 黑龙江省| 克什克腾旗| 龙山县| 乐陵市| 营口市| 称多县| 陆良县| 珠海市| 武强县| 济源市| 恩施市| 两当县| 固镇县| 奇台县| 黎川县| 比如县| 视频| 东安县| 福贡县| 满洲里市| 沙洋县| 白银市| 通化市| 龙游县| 衡山县| 新乡县|