📄 0049.htm
字号:
160 log = new PrintWriter(new FileWriter(logFile, true), true);
<br>
161 }
<br>
162 catch (IOException e) {
<br>
163 System.err.println("无法打开日志文件: " + logFile);
<br>
164 log = new PrintWriter(System.err);
<br>
165 }
<br>
166 loadDrivers(dbProps);
<br>
167 createPools(dbProps);
<br>
168 }
<br>
169
<br>
170 /**
<br>
171 * 装载和注册所有JDBC驱动程序
<br>
172 *
<br>
173 * @param props 属性
<br>
174 */
<br>
175 private void loadDrivers(Properties props) {
<br>
176 String driverClasses = props.getProperty("drivers");
<br>
177 StringTokenizer st = new StringTokenizer(driverClasses);
<br>
178 while (st.hasMoreElements()) {
<br>
179 String driverClassName = st.nextToken().trim();
<br>
180 try {
<br>
181 Driver driver = (Driver)
<br>
182 Class.forName(driverClassName).newInstance();
<br>
183 DriverManager.registerDriver(driver);
<br>
184 drivers.addElement(driver);
<br>
185 log("成功注册JDBC驱动程序" + driverClassName);
<br>
186 }
<br>
187 catch (Exception e) {
<br>
188 log("无法注册JDBC驱动程序: " +
<br>
189 driverClassName + ", 错误: " + e);
<br>
190 }
<br>
191 }
<br>
192 }
<br>
193
<br>
194 /**
<br>
195 * 将文本信息写入日志文件
<br>
196 */
<br>
197 private void log(String msg) {
<br>
198 log.println(new Date() + ": " + msg);
<br>
199 }
<br>
200
<br>
201 /**
<br>
202 * 将文本信息与异常写入日志文件
<br>
203 */
<br>
204 private void log(Throwable e, String msg) {
<br>
205 log.println(new Date() + ": " + msg);
<br>
206 e.printStackTrace(log);
<br>
207 }
<br>
208
<br>
209 /**
<br>
210 * 此内部类定义了一个连接池.它能够根据要求创建新连接,直到预定的最
<br>
211 * 大连接数为止.在返回连接给客户程序之前,它能够验证连接的有效性.
<br>
212 */
<br>
213 class DBConnectionPool {
<br>
214 private int checkedOut;
<br>
215 private Vector freeConnections = new Vector();
<br>
216 private int maxConn;
<br>
217 private String name;
<br>
218 private String password;
<br>
219 private String URL;
<br>
220 private String user;
<br>
221
<br>
222 /**
<br>
223 * 创建新的连接池
<br>
224 *
<br>
225 * @param name 连接池名字
<br>
226 * @param URL 数据库的JDBC URL
<br>
227 * @param user 数据库帐号,或 null
<br>
228 * @param password 密码,或 null
<br>
229 * @param maxConn 此连接池允许建立的最大连接数
<br>
230 */
<br>
231 public DBConnectionPool(String name, String URL, String user, String password,
<br>
232 int maxConn) {
<br>
233 this.name = name;
<br>
234 this.URL = URL;
<br>
235 this.user = user;
<br>
236 this.password = password;
<br>
237 this.maxConn = maxConn;
<br>
238 }
<br>
239
<br>
240 /**
<br>
241 * 将不再使用的连接返回给连接池
<br>
242 *
<br>
243 * @param con 客户程序释放的连接
<br>
244 */
<br>
245 public synchronized void freeConnection(Connection con) {
<br>
246 // 将指定连接加入到向量末尾
<br>
247 freeConnections.addElement(con);
<br>
248 checkedOut--;
<br>
249 notifyAll();
<br>
250 }
<br>
251
<br>
252 /**
<br>
253 * 从连接池获得一个可用连接.如没有空闲的连接且当前连接数小于最大连接
<br>
254 * 数限制,则创建新连接.如原来登记为可用的连接不再有效,则从向量删除之,
<br>
255 * 然后递归调用自己以尝试新的可用连接.
<br>
256 */
<br>
257 public synchronized Connection getConnection() {
<br>
258 Connection con = null;
<br>
259 if (freeConnections.size() > 0) {
<br>
260 // 获取向量中第一个可用连接
<br>
261 con = (Connection) freeConnections.firstElement();
<br>
262 freeConnections.removeElementAt(0);
<br>
263 try {
<br>
264 if (con.isClosed()) {
<br>
265 log("从连接池" + name+"删除一个无效连接");
<br>
266 // 递归调用自己,尝试再次获取可用连接
<br>
267 con = getConnection();
<br>
268 }
<br>
269 }
<br>
270 catch (SQLException e) {
<br>
271 log("从连接池" + name+"删除一个无效连接");
<br>
272 // 递归调用自己,尝试再次获取可用连接
<br>
273 con = getConnection();
<br>
274 }
<br>
275 }
<br>
276 else if (maxConn == 0 || checkedOut < maxConn) {
<br>
277 con = newConnection();
<br>
278 }
<br>
279 if (con != null) {
<br>
280 checkedOut++;
<br>
281 }
<br>
282 return con;
<br>
283 }
<br>
284
<br>
285 /**
<br>
286 * 从连接池获取可用连接.可以指定客户程序能够等待的最长时间
<br>
287 * 参见前一个getConnection()方法.
<br>
288 *
<br>
289 * @param timeout 以毫秒计的等待时间限制
<br>
290 */
<br>
291 public synchronized Connection getConnection(long timeout) {
<br>
292 long startTime = new Date().getTime();
<br>
293 Connection con;
<br>
294 while ((con = getConnection()) == null) {
<br>
295 try {
<br>
296 wait(timeout);
<br>
297 }
<br>
298 catch (InterruptedException e) {}
<br>
299 if ((new Date().getTime() - startTime) >= timeout) {
<br>
300 // wait()返回的原因是超时
<br>
301 return null;
<br>
302 }
<br>
303 }
<br>
304 return con;
<br>
305 }
<br>
306
<br>
307 /**
<br>
308 * 关闭所有连接
<br>
309 */
<br>
310 public synchronized void release() {
<br>
311 Enumeration allConnections = freeConnections.elements();
<br>
312 while (allConnections.hasMoreElements()) {
<br>
313 Connection con = (Connection) allConnections.nextElement();
<br>
314 try {
<br>
315 con.close();
<br>
316 log("关闭连接池" + name+"中的一个连接");
<br>
317 }
<br>
318 catch (SQLException e) {
<br>
319 log(e, "无法关闭连接池" + name+"中的连接");
<br>
320 }
<br>
321 }
<br>
322 freeConnections.removeAllElements();
<br>
323 }
<br>
324
<br>
325 /**
<br>
326 * 创建新的连接
<br>
327 */
<br>
328 private Connection newConnection() {
<br>
329 Connection con = null;
<br>
330 try {
<br>
331 if (user == null) {
<br>
332 con = DriverManager.getConnection(URL);
<br>
333 }
<br>
334 else {
<br>
335 con = DriverManager.getConnection(URL, user, password);
<br>
336 }
<br>
337 log("连接池" + name+"创建一个新的连接");
<br>
338 }
<br>
339 catch (SQLException e) {
<br>
340 log(e, "无法创建下列URL的连接: " + URL);
<br>
341 return null;
<br>
342 }
<br>
343 return con;
<br>
344 }
<br>
345 }
<br>
346 }
<br>
</table>
<p align="center"><script src="../../2.js"></script></a>
</body>
</html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -