| 发表于:2007-01-17 11:55:155楼 得分:0 |
001 import java.io.*; 002 import java.sql.*; 003 import java.util.*; 004 import java.util.date; 005 006 /** 007 * 管理类dbconnectionmanager支持对一个或多个由属性文件定义的数据库连接 008 * 池的访问.客户程序可以调用getinstance()方法访问本类的唯一实例. 009 */ 010 public class dbconnectionmanager { 011 static private dbconnectionmanager instance; // 唯一实例 012 static private int clients; 013 014 private vector drivers = new vector(); 015 private printwriter log; 016 private hashtable pools = new hashtable(); 017 018 /** 019 * 返回唯一实例.如果是第一次调用此方法,则创建实例 020 * 021 * @return dbconnectionmanager 唯一实例 022 */ 023 static synchronized public dbconnectionmanager getinstance() { 024 if (instance == null) { 025 instance = new dbconnectionmanager(); 026 } 027 clients++; 028 return instance; 029 } 030 031 /** 032 * 建构函数私有以防止其它对象创建本类实例 033 */ 034 private dbconnectionmanager() { 035 init(); 036 } 037 038 /** 039 * 将连接对象返回给由名字指定的连接池 040 * 041 * @param name 在属性文件中定义的连接池名字 042 * @param con 连接对象 043 */ 044 public void freeconnection(string name, connection con) { 045 dbconnectionpool pool = (dbconnectionpool) pools.get(name); 046 if (pool != null) { 047 pool.freeconnection(con); 048 } 049 } 050 051 /** 052 * 获得一个可用的(空闲的)连接.如果没有可用连接,且已有连接数小于最大连接数 053 * 限制,则创建并返回新连接 054 * 055 * @param name 在属性文件中定义的连接池名字 056 * @return connection 可用连接或null 057 */ 058 public connection getconnection(string name) { 059 dbconnectionpool pool = (dbconnectionpool) pools.get(name); 060 if (pool != null) { 061 return pool.getconnection(); 062 } 063 return null; 064 } 065 066 /** 067 * 获得一个可用连接.若没有可用连接,且已有连接数小于最大连接数限制, 068 * 则创建并返回新连接.否则,在指定的时间内等待其它线程释放连接. 069 * 070 * @param name 连接池名字 071 * @param time 以毫秒计的等待时间 072 * @return connection 可用连接或null 073 */ 074 public connection getconnection(string name, long time) { 075 dbconnectionpool pool = (dbconnectionpool) pools.get(name); 076 if (pool != null) { 077 return pool.getconnection(time); 078 } 079 return null; 080 } 081 082 /** 083 * 关闭所有连接,撤销驱动程序的注册 084 */ 085 public synchronized void release() { 086 // 等待直到最后一个客户程序调用 087 if (--clients != 0) { 088 return; 089 } 090 091 enumeration allpools = pools.elements(); 092 while (allpools.hasmoreelements()) { 093 dbconnectionpool pool = (dbconnectionpool) allpools.nextelement(); 094 pool.release(); 095 } 096 enumeration alldrivers = drivers.elements(); 097 while (alldrivers.hasmoreelements()) { 098 driver driver = (driver) alldrivers.nextelement(); 099 try { 100 drivermanager.deregisterdriver(driver); 101 log( "撤销jdbc驱动程序 " + driver.getclass().getname()+ "的注册 "); 102 } 103 catch (sqlexception e) { 104 log(e, "无法撤销下列jdbc驱动程序的注册: " + driver.getclass().getname()); 105 } 106 } 107 } 108 109 /** 110 * 根据指定属性创建连接池实例. 111 * 112 * @param props 连接池属性 113 */ 114 private void createpools(properties props) { 115 enumeration propnames = props.propertynames(); 116 while (propnames.hasmoreelements()) { 117 string name = (string) propnames.nextelement(); 118 if (name.endswith( ".url ")) { 119 string poolname = name.substring(0, name.lastindexof( ". ")); 120 string url = props.getproperty(poolname + ".url "); 121 if (url == null) { 122 log( "没有为连接池 " + poolname + "指定url "); 123 continue; 124 } 125 string user = props.getproperty(poolname + ".user "); 126 string password = props.getproperty(poolname + ".password "); 127 string maxconn = props.getproperty(poolname + ".maxconn ", "0 "); 128 int max; 129 try { 130 max = integer.valueof(maxconn).intvalue(); 131 } 132 catch (numberformatexception e) { 133 log( "错误的最大连接数限制: " + maxconn + " .连接池: " + poolname); 134 max = 0; 135 } 136 dbconnectionpool pool = 137 new dbconnectionpool(poolname, url, user, password, max); 138 pools.put(poolname, pool); 139 log( "成功创建连接池 " + poolname); 140 } 141 } 142 } 143 144 /** 145 * 读取属性完成初始化 146 */ 147 private void init() { 148 inputstream is = getclass().getresourceasstream( "/db.properties "); 149 properties dbprops = new properties(); 150 try { 151 dbprops.load(is); 152 } 153 catch (exception e) { 154 system.err.println( "不能读取属性文件. " + 155 "请确保db.properties在classpath指定的路径中 "); 156 return; 157 } 158 string logfile = dbprops.getproperty( "logfile ", "dbconnectionmanager.log "); 159 try { 160 log = new printwriter(new filewriter(logfile, true), true); 161 } 162 catch (ioexception e) { 163 system.err.println( "无法打开日志文件: " + logfile); 164 log = new printwriter(system.err); 165 } 166 loaddrivers(dbprops); 167 createpools(dbprops); 168 } 169 170 /** 171 * 装载和注册所有jdbc驱动程序 172 * 173 * @param props 属性 174 */ 175 private void loaddrivers(properties props) { 176 string driverclasses = props.getproperty( "drivers "); 177 stringtokenizer st = new stringtokenizer(driverclasses); 178 while (st.hasmoreelements()) { 179 string driverclassname = st.nexttoken().trim(); 180 try { 181 driver driver = (driver) 182 class.forname(driverclassname).newinstance(); 183 drivermanager.registerdriver(driver); 184 drivers.addelement(driver); 185 log( "成功注册jdbc驱动程序 " + driverclassname); 186 } 187 catch (exception e) { 188 log( "无法注册jdbc驱动程序: " + 189 driverclassname + ", 错误: " + e); 190 } 191 } 192 } 193 194 /** 195 * 将文本信息写入日志文件 196 */ | | |
|