虽然现在用APACHE COMMONS DBCP可以非常方便的建立数据库连接池,
但是像这篇文章把数据库连接池的内部原理写的这么透彻,注视这么完整,
真是非常难得,让开发人员可以更深层次的理解数据库连接池,真是非常感
谢这篇文章的作者。
1
import java.sql.Connection;
2
import java.sql.DatabaseMetaData;
3
import java.sql.Driver;
4
import java.sql.DriverManager;
5
import java.sql.SQLException;
6
import java.sql.Statement;
7
import java.util.Enumeration;
8
import java.util.Vector;
9![](/Images/OutliningIndicators/None.gif)
10![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
public class ConnectionPool
{
11![](/Images/OutliningIndicators/InBlock.gif)
12
private String _jdbcDriver = ""; // 数据库驱动
13![](/Images/OutliningIndicators/InBlock.gif)
14
private String _dbUrl = ""; // 数据 URL
15![](/Images/OutliningIndicators/InBlock.gif)
16
private String _dbUsername = ""; // 数据库用户名
17![](/Images/OutliningIndicators/InBlock.gif)
18
private String _dbPassword = ""; // 数据库用户密码
19![](/Images/OutliningIndicators/InBlock.gif)
20
private String _testTable = ""; // 测试连接是否可用的测试表名,默认没有测试表
21![](/Images/OutliningIndicators/InBlock.gif)
22
private int _initialConnections = 20; // 连接池的初始大小
23![](/Images/OutliningIndicators/InBlock.gif)
24
private int _incrementalConnections = 5;// 连接池自动增加的大小
25![](/Images/OutliningIndicators/InBlock.gif)
26
private int _maxConnections = 50; // 连接池最大的大小
27![](/Images/OutliningIndicators/InBlock.gif)
28
private Vector _connectionVector = null; // 存放连接池中数据库连接的向量 , 初始时为 null
29![](/Images/OutliningIndicators/InBlock.gif)
30
// 它中存放的对象为 PooledConnection 型
31![](/Images/OutliningIndicators/InBlock.gif)
32![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/** *//**
33
*
34
* 构造函数
35
*
36
*
37
*
38
* @param jdbcDriver
39
* String JDBC 驱动类串
40
*
41
* @param dbUrl
42
* String 数据库 URL
43
*
44
* @param dbUsername
45
* String 连接数据库用户名
46
*
47
* @param dbPassword
48
* String 连接数据库用户的密码
49
*
50
*
51
*
52
*/
53![](/Images/OutliningIndicators/InBlock.gif)
54
public ConnectionPool(String jdbcDriver, String dbUrl, String dbUsername,
55![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
String dbPassword)
{
56
57
this._jdbcDriver = jdbcDriver;
58![](/Images/OutliningIndicators/InBlock.gif)
59
this._dbUrl = dbUrl;
60![](/Images/OutliningIndicators/InBlock.gif)
61
this._dbUsername = dbUsername;
62![](/Images/OutliningIndicators/InBlock.gif)
63
this._dbPassword = dbPassword;
64![](/Images/OutliningIndicators/InBlock.gif)
65
}
66![](/Images/OutliningIndicators/InBlock.gif)
67![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/** *//**
68
*
69
* 返回连接池的初始大小
70
*
71
*
72
*
73
* @return 初始连接池中可获得的连接数量
74
*
75
*/
76![](/Images/OutliningIndicators/InBlock.gif)
77![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public int getInitialConnections()
{
78![](/Images/OutliningIndicators/InBlock.gif)
79
return this._initialConnections;
80![](/Images/OutliningIndicators/InBlock.gif)
81
}
82![](/Images/OutliningIndicators/InBlock.gif)
83![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/** *//**
84
*
85
* 设置连接池的初始大小
86
*
87
*
88
*
89
* @param 用于设置初始连接池中连接的数量
90
*
91
*/
92![](/Images/OutliningIndicators/InBlock.gif)
93![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public void setInitialConnections(int initialConnections)
{
94![](/Images/OutliningIndicators/InBlock.gif)
95
this._initialConnections = initialConnections;
96![](/Images/OutliningIndicators/InBlock.gif)
97
}
98![](/Images/OutliningIndicators/InBlock.gif)
99![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/** *//**
100
*
101
* 返回连接池自动增加的大小
102
*
103
*
104
*
105
* @return 连接池自动增加的大小
106
*
107
*/
108![](/Images/OutliningIndicators/InBlock.gif)
109![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public int getIncrementalConnections()
{
110![](/Images/OutliningIndicators/InBlock.gif)
111
return this._incrementalConnections;
112![](/Images/OutliningIndicators/InBlock.gif)
113
}
114![](/Images/OutliningIndicators/InBlock.gif)
115![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/** *//**
116
*
117
* 设置连接池自动增加的大小
118
*
119
* @param 连接池自动增加的大小
120
*
121
*/
122![](/Images/OutliningIndicators/InBlock.gif)
123![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public void setIncrementalConnections(int incrementalConnections)
{
124![](/Images/OutliningIndicators/InBlock.gif)
125
this._incrementalConnections = incrementalConnections;
126![](/Images/OutliningIndicators/InBlock.gif)
127
}
128![](/Images/OutliningIndicators/InBlock.gif)
129![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/** *//**
130
*
131
* 返回连接池中最大的可用连接数量
132
*
133
* @return 连接池中最大的可用连接数量
134
*
135
*/
136![](/Images/OutliningIndicators/InBlock.gif)
137![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public int getMaxConnections()
{
138![](/Images/OutliningIndicators/InBlock.gif)
139
return this._maxConnections;
140![](/Images/OutliningIndicators/InBlock.gif)
141
}
142![](/Images/OutliningIndicators/InBlock.gif)
143![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/** *//**
144
*
145
* 设置连接池中最大可用的连接数量
146
*
147
*
148
*
149
* @param 设置连接池中最大可用的连接数量值
150
*
151
*/
152![](/Images/OutliningIndicators/InBlock.gif)
153![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public void setMaxConnections(int maxConnections)
{
154![](/Images/OutliningIndicators/InBlock.gif)
155
this._maxConnections = maxConnections;
156![](/Images/OutliningIndicators/InBlock.gif)
157
}
158![](/Images/OutliningIndicators/InBlock.gif)
159![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/** *//**
160
*
161
* 获取测试数据库表的名字
162
*
163
*
164
*
165
* @return 测试数据库表的名字
166
*
167
*/
168![](/Images/OutliningIndicators/InBlock.gif)
169![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public String getTestTable()
{
170![](/Images/OutliningIndicators/InBlock.gif)
171
return this._testTable;
172![](/Images/OutliningIndicators/InBlock.gif)
173
}
174![](/Images/OutliningIndicators/InBlock.gif)
175![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/** *//**
176
*
177
* 设置测试表的名字
178
*
179
* @param testTable
180
* String 测试表的名字
181
*
182
*/
183![](/Images/OutliningIndicators/InBlock.gif)
184![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public void setTestTable(String testTable)
{
185![](/Images/OutliningIndicators/InBlock.gif)
186
this._testTable = testTable;
187![](/Images/OutliningIndicators/InBlock.gif)
188
}
189![](/Images/OutliningIndicators/InBlock.gif)
190![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/** *//**
191
*
192
*
193
*
194
* 创建一个数据库连接池,连接池中的可用连接的数量采用类成员
195
*
196
* initialConnections 中设置的值
197
*
198
*/
199![](/Images/OutliningIndicators/InBlock.gif)
200![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public synchronized void createPool() throws Exception
{
201![](/Images/OutliningIndicators/InBlock.gif)
202
// 确保连接池没有创建
203![](/Images/OutliningIndicators/InBlock.gif)
204
// 如果连接池己经创建了,保存连接的向量 connections 不会为空
205![](/Images/OutliningIndicators/InBlock.gif)
206![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (_connectionVector != null)
{
207![](/Images/OutliningIndicators/InBlock.gif)
208
return; // 如果己经创建,则返回
209![](/Images/OutliningIndicators/InBlock.gif)
210
}
211![](/Images/OutliningIndicators/InBlock.gif)
212
// 实例化 JDBC Driver 中指定的驱动类实例
213![](/Images/OutliningIndicators/InBlock.gif)
214
Driver driver = (Driver) (Class.forName(this._jdbcDriver).newInstance());
215![](/Images/OutliningIndicators/InBlock.gif)
216
DriverManager.registerDriver(driver); // 注册 JDBC 驱动程序
217![](/Images/OutliningIndicators/InBlock.gif)
218
// 创建保存连接的向量 , 初始时有 0 个元素
219![](/Images/OutliningIndicators/InBlock.gif)
220
_connectionVector = new Vector();
221![](/Images/OutliningIndicators/InBlock.gif)
222
// 根据 initialConnections 中设置的值,创建连接。
223![](/Images/OutliningIndicators/InBlock.gif)
224
createConnections(this._initialConnections);
225![](/Images/OutliningIndicators/InBlock.gif)
226
System.out.println(" 数据库连接池创建成功! ");
227![](/Images/OutliningIndicators/InBlock.gif)
228
}
229![](/Images/OutliningIndicators/InBlock.gif)
230![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/** *//**
231
*
232
* 创建由 numConnections 指定数目的数据库连接 , 并把这些连接
233
*
234
* 放入 connections 向量中
235
*
236
*
237
*
238
* @param numConnections
239
* 要创建的数据库连接的数目
240
*
241
*/
242![](/Images/OutliningIndicators/InBlock.gif)
243
@SuppressWarnings("unchecked")
244![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
private void createConnections(int numConnections) throws SQLException
{
245![](/Images/OutliningIndicators/InBlock.gif)
246
// 循环创建指定数目的数据库连接
247![](/Images/OutliningIndicators/InBlock.gif)
248![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
for (int x = 0; x < numConnections; x++)
{
249![](/Images/OutliningIndicators/InBlock.gif)
250
// 是否连接池中的数据库连接的数量己经达到最大?最大值由类成员 maxConnections
251![](/Images/OutliningIndicators/InBlock.gif)
252
// 指出,如果 maxConnections 为 0 或负数,表示连接数量没有限制。
253![](/Images/OutliningIndicators/InBlock.gif)
254
// 如果连接数己经达到最大,即退出。
255![](/Images/OutliningIndicators/InBlock.gif)
256
if (this._maxConnections > 0
257![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
&& this._connectionVector.size() >= this._maxConnections)
{
258![](/Images/OutliningIndicators/InBlock.gif)
259
break;
260![](/Images/OutliningIndicators/InBlock.gif)
261
}
262![](/Images/OutliningIndicators/InBlock.gif)
263
// add a new PooledConnection object to connections vector
264![](/Images/OutliningIndicators/InBlock.gif)
265
// 增加一个连接到连接池中(向量 connections 中)
266![](/Images/OutliningIndicators/InBlock.gif)
267![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
try
{
268![](/Images/OutliningIndicators/InBlock.gif)
269
_connectionVector.addElement(new PooledConnection(newConnection()));
270![](/Images/OutliningIndicators/InBlock.gif)
271![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
} catch (SQLException e)
{
272![](/Images/OutliningIndicators/InBlock.gif)
273
System.out.println(" 创建数据库连接失败! " + e.getMessage());
274![](/Images/OutliningIndicators/InBlock.gif)
275
throw new SQLException();
276![](/Images/OutliningIndicators/InBlock.gif)
277
}
278![](/Images/OutliningIndicators/InBlock.gif)
279
System.out.println(" 数据库连接己创建 ![](http://www.blogjava.net/Images/dot.gif)
");
280![](/Images/OutliningIndicators/InBlock.gif)
281
}
282![](/Images/OutliningIndicators/InBlock.gif)
283
}
284![](/Images/OutliningIndicators/InBlock.gif)
285![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/** *//**
286
*
287
* 创建一个新的数据库连接并返回它
288
*
289
*
290
*
291
* @return 返回一个新创建的数据库连接
292
*
293
*/
294![](/Images/OutliningIndicators/InBlock.gif)
295![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
private Connection newConnection() throws SQLException
{
296![](/Images/OutliningIndicators/InBlock.gif)
297
// 创建一个数据库连接
298![](/Images/OutliningIndicators/InBlock.gif)
299
Connection conn = DriverManager.getConnection(_dbUrl, _dbUsername,
300
_dbPassword);
301![](/Images/OutliningIndicators/InBlock.gif)
302
// 如果这是第一次创建数据库连接,即检查数据库,获得此数据库允许支持的
303![](/Images/OutliningIndicators/InBlock.gif)
304
// 最大客户连接数目
305![](/Images/OutliningIndicators/InBlock.gif)
306
// connections.size()==0 表示目前没有连接己被创建
307![](/Images/OutliningIndicators/InBlock.gif)
308![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (_connectionVector.size() == 0)
{
309![](/Images/OutliningIndicators/InBlock.gif)
310
DatabaseMetaData metaData = conn.getMetaData();
311![](/Images/OutliningIndicators/InBlock.gif)
312
int driverMaxConnections = metaData.getMaxConnections();
313![](/Images/OutliningIndicators/InBlock.gif)
314
// 数据库返回的 driverMaxConnections 若为 0 ,表示此数据库没有最大
315![](/Images/OutliningIndicators/InBlock.gif)
316
// 连接限制,或数据库的最大连接限制不知道
317![](/Images/OutliningIndicators/InBlock.gif)
318
// driverMaxConnections 为返回的一个整数,表示此数据库允许客户连接的数目
319![](/Images/OutliningIndicators/InBlock.gif)
320
// 如果连接池中设置的最大连接数量大于数据库允许的连接数目 , 则置连接池的最大
321![](/Images/OutliningIndicators/InBlock.gif)
322
// 连接数目为数据库允许的最大数目
323![](/Images/OutliningIndicators/InBlock.gif)
324
if (driverMaxConnections > 0
325![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
&& this._maxConnections > driverMaxConnections)
{
326![](/Images/OutliningIndicators/InBlock.gif)
327
this._maxConnections = driverMaxConnections;
328![](/Images/OutliningIndicators/InBlock.gif)
329
}
330![](/Images/OutliningIndicators/InBlock.gif)
331
}
332![](/Images/OutliningIndicators/InBlock.gif)
333
return conn; // 返回创建的新的数据库连接
334![](/Images/OutliningIndicators/InBlock.gif)
335
}
336![](/Images/OutliningIndicators/InBlock.gif)
337![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/** *//**
338
*
339
* 通过调用 getFreeConnection() 函数返回一个可用的数据库连接 ,
340
*
341
* 如果当前没有可用的数据库连接,并且更多的数据库连接不能创
342
*
343
* 建(如连接池大小的限制),此函数等待一会再尝试获取。
344
*
345
*
346
*
347
* @return 返回一个可用的数据库连接对象
348
*
349
*/
350![](/Images/OutliningIndicators/InBlock.gif)
351![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public synchronized Connection getConnection() throws SQLException
{
352![](/Images/OutliningIndicators/InBlock.gif)
353
// 确保连接池己被创建
354![](/Images/OutliningIndicators/InBlock.gif)
355![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (_connectionVector == null)
{
356![](/Images/OutliningIndicators/InBlock.gif)
357
return null; // 连接池还没创建,则返回 null
358![](/Images/OutliningIndicators/InBlock.gif)
359
}
360![](/Images/OutliningIndicators/InBlock.gif)
361
Connection conn = getFreeConnection(); // 获得一个可用的数据库连接
362![](/Images/OutliningIndicators/InBlock.gif)
363
// 如果目前没有可以使用的连接,即所有的连接都在使用中
364![](/Images/OutliningIndicators/InBlock.gif)
365![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
while (conn == null)
{
366![](/Images/OutliningIndicators/InBlock.gif)
367
// 等一会再试
368![](/Images/OutliningIndicators/InBlock.gif)
369
wait(250);
370![](/Images/OutliningIndicators/InBlock.gif)
371
conn = getFreeConnection(); // 重新再试,直到获得可用的连接,如果
372![](/Images/OutliningIndicators/InBlock.gif)
373
// getFreeConnection() 返回的为 null
374![](/Images/OutliningIndicators/InBlock.gif)
375
// 则表明创建一批连接后也不可获得可用连接
376![](/Images/OutliningIndicators/InBlock.gif)
377
}
378![](/Images/OutliningIndicators/InBlock.gif)
379
return conn;// 返回获得的可用的连接
380![](/Images/OutliningIndicators/InBlock.gif)
381
}
382![](/Images/OutliningIndicators/InBlock.gif)
383![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/** *//**
384
*
385
* 本函数从连接池向量 connections 中返回一个可用的的数据库连接,如果
386
*
387
* 当前没有可用的数据库连接,本函数则根据 incrementalConnections 设置
388
*
389
* 的值创建几个数据库连接,并放入连接池中。
390
*
391
* 如果创建后,所有的连接仍都在使用中,则返回 null
392
*
393
* @return 返回一个可用的数据库连接
394
*
395
*/
396![](/Images/OutliningIndicators/InBlock.gif)
397![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
private Connection getFreeConnection() throws SQLException
{
398![](/Images/OutliningIndicators/InBlock.gif)
399
// 从连接池中获得一个可用的数据库连接
400![](/Images/OutliningIndicators/InBlock.gif)
401
Connection conn = findFreeConnection();
402![](/Images/OutliningIndicators/InBlock.gif)
403![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (conn == null)
{
404![](/Images/OutliningIndicators/InBlock.gif)
405
// 如果目前连接池中没有可用的连接
406![](/Images/OutliningIndicators/InBlock.gif)
407
// 创建一些连接
408![](/Images/OutliningIndicators/InBlock.gif)
409
createConnections(_incrementalConnections);
410![](/Images/OutliningIndicators/InBlock.gif)
411
// 重新从池中查找是否有可用连接
412![](/Images/OutliningIndicators/InBlock.gif)
413
conn = findFreeConnection();
414![](/Images/OutliningIndicators/InBlock.gif)
415![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (conn == null)
{
416![](/Images/OutliningIndicators/InBlock.gif)
417
// 如果创建连接后仍获得不到可用的连接,则返回 null
418![](/Images/OutliningIndicators/InBlock.gif)
419
return null;
420![](/Images/OutliningIndicators/InBlock.gif)
421
}
422![](/Images/OutliningIndicators/InBlock.gif)
423
}
424![](/Images/OutliningIndicators/InBlock.gif)
425
return conn;
426![](/Images/OutliningIndicators/InBlock.gif)
427
}
428![](/Images/OutliningIndicators/InBlock.gif)
429![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/** *//**
430
*
431
* 查找连接池中所有的连接,查找一个可用的数据库连接,
432
*
433
* 如果没有可用的连接,返回 null
434
*
435
*
436
*
437
* @return 返回一个可用的数据库连接
438
*
439
*/
440![](/Images/OutliningIndicators/InBlock.gif)
441![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
private Connection findFreeConnection() throws SQLException
{
442![](/Images/OutliningIndicators/InBlock.gif)
443
Connection conn = null;
444![](/Images/OutliningIndicators/InBlock.gif)
445
PooledConnection pConn = null;
446![](/Images/OutliningIndicators/InBlock.gif)
447
// 获得连接池向量中所有的对象
448![](/Images/OutliningIndicators/InBlock.gif)
449
Enumeration enumerate = _connectionVector.elements();
450![](/Images/OutliningIndicators/InBlock.gif)
451
// 遍历所有的对象,看是否有可用的连接
452![](/Images/OutliningIndicators/InBlock.gif)
453![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
while (enumerate.hasMoreElements())
{
454![](/Images/OutliningIndicators/InBlock.gif)
455
pConn = (PooledConnection) enumerate.nextElement();
456![](/Images/OutliningIndicators/InBlock.gif)
457![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (!pConn.isBusy())
{
458![](/Images/OutliningIndicators/InBlock.gif)
459
// 如果此对象不忙,则获得它的数据库连接并把它设为忙
460![](/Images/OutliningIndicators/InBlock.gif)
461
conn = pConn.getConnection();
462![](/Images/OutliningIndicators/InBlock.gif)
463
pConn.setBusy(true);
464![](/Images/OutliningIndicators/InBlock.gif)
465
// 测试此连接是否可用
466![](/Images/OutliningIndicators/InBlock.gif)
467![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (!testConnection(conn))
{
468![](/Images/OutliningIndicators/InBlock.gif)
469
// 如果此连接不可再用了,则创建一个新的连接,
470![](/Images/OutliningIndicators/InBlock.gif)
471
// 并替换此不可用的连接对象,如果创建失败,返回 null
472![](/Images/OutliningIndicators/InBlock.gif)
473![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
try
{
474![](/Images/OutliningIndicators/InBlock.gif)
475
conn = newConnection();
476![](/Images/OutliningIndicators/InBlock.gif)
477![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
} catch (SQLException e)
{
478![](/Images/OutliningIndicators/InBlock.gif)
479
System.out.println(" 创建数据库连接失败! " + e.getMessage());
480![](/Images/OutliningIndicators/InBlock.gif)
481
return null;
482![](/Images/OutliningIndicators/InBlock.gif)
483
}
484![](/Images/OutliningIndicators/InBlock.gif)
485
pConn.setConnection(conn);
486![](/Images/OutliningIndicators/InBlock.gif)
487
}
488![](/Images/OutliningIndicators/InBlock.gif)
489
break; // 己经找到一个可用的连接,退出
490![](/Images/OutliningIndicators/InBlock.gif)
491
}
492![](/Images/OutliningIndicators/InBlock.gif)
493
}
494![](/Images/OutliningIndicators/InBlock.gif)
495
return conn;// 返回找到到的可用连接
496![](/Images/OutliningIndicators/InBlock.gif)
497
}
498![](/Images/OutliningIndicators/InBlock.gif)
499![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/** *//**
500
*
501
* 测试一个连接是否可用,如果不可用,关掉它并返回 false
502
*
503
* 否则可用返回 true
504
*
505
*
506
*
507
* @param conn
508
* 需要测试的数据库连接
509
*
510
* @return 返回 true 表示此连接可用, false 表示不可用
511
*
512
*/
513![](/Images/OutliningIndicators/InBlock.gif)
514![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
private boolean testConnection(Connection conn)
{
515![](/Images/OutliningIndicators/InBlock.gif)
516![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
try
{
517![](/Images/OutliningIndicators/InBlock.gif)
518
// 判断测试表是否存在
519![](/Images/OutliningIndicators/InBlock.gif)
520![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (_testTable.equals(""))
{
521![](/Images/OutliningIndicators/InBlock.gif)
522
// 如果测试表为空,试着使用此连接的 setAutoCommit() 方法
523![](/Images/OutliningIndicators/InBlock.gif)
524
// 来判断连接否可用(此方法只在部分数据库可用,如果不可用 ,
525![](/Images/OutliningIndicators/InBlock.gif)
526
// 抛出异常)。注意:使用测试表的方法更可靠
527![](/Images/OutliningIndicators/InBlock.gif)
528
conn.setAutoCommit(true);
529![](/Images/OutliningIndicators/InBlock.gif)
530![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
} else
{// 有测试表的时候使用测试表测试
531![](/Images/OutliningIndicators/InBlock.gif)
532
// check if this connection is valid
533![](/Images/OutliningIndicators/InBlock.gif)
534
Statement stmt = conn.createStatement();
535![](/Images/OutliningIndicators/InBlock.gif)
536
stmt.execute("select count(*) from " + _testTable);
537![](/Images/OutliningIndicators/InBlock.gif)
538
}
539![](/Images/OutliningIndicators/InBlock.gif)
540![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
} catch (SQLException e)
{
541![](/Images/OutliningIndicators/InBlock.gif)
542
// 上面抛出异常,此连接己不可用,关闭它,并返回 false;
543![](/Images/OutliningIndicators/InBlock.gif)
544
closeConnection(conn);
545![](/Images/OutliningIndicators/InBlock.gif)
546
return false;
547![](/Images/OutliningIndicators/InBlock.gif)
548
}
549![](/Images/OutliningIndicators/InBlock.gif)
550
// 连接可用,返回 true
551![](/Images/OutliningIndicators/InBlock.gif)
552
return true;
553![](/Images/OutliningIndicators/InBlock.gif)
554
}
555![](/Images/OutliningIndicators/InBlock.gif)
556![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/** *//**
557
*
558
* 此函数返回一个数据库连接到连接池中,并把此连接置为空闲。
559
*
560
* 所有使用连接池获得的数据库连接均应在不使用此连接时返回它。
561
*
562
*
563
*
564
* @param 需返回到连接池中的连接对象
565
*
566
*/
567![](/Images/OutliningIndicators/InBlock.gif)
568![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public void returnConnection(Connection conn)
{
569![](/Images/OutliningIndicators/InBlock.gif)
570
// 确保连接池存在,如果连接没有创建(不存在),直接返回
571![](/Images/OutliningIndicators/InBlock.gif)
572![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (_connectionVector == null)
{
573![](/Images/OutliningIndicators/InBlock.gif)
574
System.out.println(" 连接池不存在,无法返回此连接到连接池中 !");
575![](/Images/OutliningIndicators/InBlock.gif)
576
return;
577![](/Images/OutliningIndicators/InBlock.gif)
578
}
579![](/Images/OutliningIndicators/InBlock.gif)
580
PooledConnection pConn = null;
581![](/Images/OutliningIndicators/InBlock.gif)
582
Enumeration enumerate = _connectionVector.elements();
583![](/Images/OutliningIndicators/InBlock.gif)
584
// 遍历连接池中的所有连接,找到这个要返回的连接对象
585![](/Images/OutliningIndicators/InBlock.gif)
586![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
while (enumerate.hasMoreElements())
{
587![](/Images/OutliningIndicators/InBlock.gif)
588
pConn = (PooledConnection) enumerate.nextElement();
589![](/Images/OutliningIndicators/InBlock.gif)
590
// 先找到连接池中的要返回的连接对象
591![](/Images/OutliningIndicators/InBlock.gif)
592![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (conn == pConn.getConnection())
{
593![](/Images/OutliningIndicators/InBlock.gif)
594
// 找到了 , 设置此连接为空闲状态
595![](/Images/OutliningIndicators/InBlock.gif)
596
pConn.setBusy(false);
597![](/Images/OutliningIndicators/InBlock.gif)
598
break;
599![](/Images/OutliningIndicators/InBlock.gif)
600
}
601![](/Images/OutliningIndicators/InBlock.gif)
602
}
603![](/Images/OutliningIndicators/InBlock.gif)
604
}
605![](/Images/OutliningIndicators/InBlock.gif)
606![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/** *//**
607
*
608
* 刷新连接池中所有的连接对象
609
*
610
*
611
*
612
*/
613![](/Images/OutliningIndicators/InBlock.gif)
614![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public synchronized void refreshConnections() throws SQLException
{
615![](/Images/OutliningIndicators/InBlock.gif)
616
// 确保连接池己创新存在
617![](/Images/OutliningIndicators/InBlock.gif)
618![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (_connectionVector == null)
{
619![](/Images/OutliningIndicators/InBlock.gif)
620
System.out.println(" 连接池不存在,无法刷新 !");
621![](/Images/OutliningIndicators/InBlock.gif)
622
return;
623![](/Images/OutliningIndicators/InBlock.gif)
624
}
625![](/Images/OutliningIndicators/InBlock.gif)
626
PooledConnection pConn = null;
627![](/Images/OutliningIndicators/InBlock.gif)
628
Enumeration enumerate = _connectionVector.elements();
629![](/Images/OutliningIndicators/InBlock.gif)
630![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
while (enumerate.hasMoreElements())
{
631![](/Images/OutliningIndicators/InBlock.gif)
632
// 获得一个连接对象
633![](/Images/OutliningIndicators/InBlock.gif)
634
pConn = (PooledConnection) enumerate.nextElement();
635![](/Images/OutliningIndicators/InBlock.gif)
636
// 如果对象忙则等 5 秒 ,5 秒后直接刷新
637![](/Images/OutliningIndicators/InBlock.gif)
638![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (pConn.isBusy())
{
639![](/Images/OutliningIndicators/InBlock.gif)
640
wait(5000); // 等 5 秒
641![](/Images/OutliningIndicators/InBlock.gif)
642
}
643![](/Images/OutliningIndicators/InBlock.gif)
644
// 关闭此连接,用一个新的连接代替它。
645![](/Images/OutliningIndicators/InBlock.gif)
646
closeConnection(pConn.getConnection());
647![](/Images/OutliningIndicators/InBlock.gif)
648
pConn.setConnection(newConnection());
649![](/Images/OutliningIndicators/InBlock.gif)
650
pConn.setBusy(false);
651![](/Images/OutliningIndicators/InBlock.gif)
652
}
653![](/Images/OutliningIndicators/InBlock.gif)
654
}
655![](/Images/OutliningIndicators/InBlock.gif)
656![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/** *//**
657
*
658
* 关闭连接池中所有的连接,并清空连接池。
659
*
660
*/
661![](/Images/OutliningIndicators/InBlock.gif)
662![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public synchronized void closeConnectionPool() throws SQLException
{
663![](/Images/OutliningIndicators/InBlock.gif)
664
// 确保连接池存在,如果不存在,返回
665![](/Images/OutliningIndicators/InBlock.gif)
666![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (_connectionVector == null)
{
667![](/Images/OutliningIndicators/InBlock.gif)
668
System.out.println(" 连接池不存在,无法关闭 !");
669![](/Images/OutliningIndicators/InBlock.gif)
670
return;
671![](/Images/OutliningIndicators/InBlock.gif)
672
}
673![](/Images/OutliningIndicators/InBlock.gif)
674
PooledConnection pConn = null;
675![](/Images/OutliningIndicators/InBlock.gif)
676
Enumeration enumerate = _connectionVector.elements();
677![](/Images/OutliningIndicators/InBlock.gif)
678![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
while (enumerate.hasMoreElements())
{
679![](/Images/OutliningIndicators/InBlock.gif)
680
pConn = (PooledConnection) enumerate.nextElement();
681![](/Images/OutliningIndicators/InBlock.gif)
682
// 如果忙,等 5 秒
683![](/Images/OutliningIndicators/InBlock.gif)
684![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (pConn.isBusy())
{
685![](/Images/OutliningIndicators/InBlock.gif)
686
wait(5000); // 等 5 秒
687![](/Images/OutliningIndicators/InBlock.gif)
688
}
689![](/Images/OutliningIndicators/InBlock.gif)
690
// 5 秒后直接关闭它
691![](/Images/OutliningIndicators/InBlock.gif)
692
closeConnection(pConn.getConnection());
693![](/Images/OutliningIndicators/InBlock.gif)
694
// 从连接池向量中删除它
695![](/Images/OutliningIndicators/InBlock.gif)
696
_connectionVector.removeElement(pConn);
697![](/Images/OutliningIndicators/InBlock.gif)
698
}
699![](/Images/OutliningIndicators/InBlock.gif)
700
// 置连接池为空
701![](/Images/OutliningIndicators/InBlock.gif)
702
_connectionVector = null;
703![](/Images/OutliningIndicators/InBlock.gif)
704
}
705![](/Images/OutliningIndicators/InBlock.gif)
706![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/** *//**
707
*
708
* 关闭一个数据库连接
709
*
710
*
711
*
712
* @param 需要关闭的数据库连接
713
*
714
*/
715![](/Images/OutliningIndicators/InBlock.gif)
716![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
private void closeConnection(Connection conn)
{
717![](/Images/OutliningIndicators/InBlock.gif)
718![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
try
{
719![](/Images/OutliningIndicators/InBlock.gif)
720
conn.close();
721![](/Images/OutliningIndicators/InBlock.gif)
722![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
} catch (SQLException e)
{
723![](/Images/OutliningIndicators/InBlock.gif)
724
System.out.println(" 关闭数据库连接出错: " + e.getMessage());
725![](/Images/OutliningIndicators/InBlock.gif)
726
}
727![](/Images/OutliningIndicators/InBlock.gif)
728
}
729![](/Images/OutliningIndicators/InBlock.gif)
730![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/** *//**
731
*
732
* 使程序等待给定的毫秒数
733
*
734
*
735
*
736
* @param 给定的毫秒数
737
*
738
*/
739![](/Images/OutliningIndicators/InBlock.gif)
740![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
private void wait(int mSeconds)
{
741![](/Images/OutliningIndicators/InBlock.gif)
742![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
try
{
743![](/Images/OutliningIndicators/InBlock.gif)
744
Thread.sleep(mSeconds);
745![](/Images/OutliningIndicators/InBlock.gif)
746![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
} catch (InterruptedException e)
{
747![](/Images/OutliningIndicators/InBlock.gif)
748
}
749![](/Images/OutliningIndicators/InBlock.gif)
750
}
751![](/Images/OutliningIndicators/InBlock.gif)
752![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/** *//**
753
*
754
*
755
*
756
* 内部使用的用于保存连接池中连接对象的类
757
*
758
* 此类中有两个成员,一个是数据库的连接,另一个是指示此连接是否
759
*
760
* 正在使用的标志。
761
*
762
*/
763![](/Images/OutliningIndicators/InBlock.gif)
764![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
class PooledConnection
{
765![](/Images/OutliningIndicators/InBlock.gif)
766
Connection connection = null;// 数据库连接
767![](/Images/OutliningIndicators/InBlock.gif)
768
boolean busy = false; // 此连接是否正在使用的标志,默认没有正在使用
769![](/Images/OutliningIndicators/InBlock.gif)
770
// 构造函数,根据一个 Connection 构告一个 PooledConnection 对象
771![](/Images/OutliningIndicators/InBlock.gif)
772![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public PooledConnection(Connection connection)
{
773![](/Images/OutliningIndicators/InBlock.gif)
774
this.connection = connection;
775![](/Images/OutliningIndicators/InBlock.gif)
776
}
777![](/Images/OutliningIndicators/InBlock.gif)
778
// 返回此对象中的连接
779![](/Images/OutliningIndicators/InBlock.gif)
780![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public Connection getConnection()
{
781![](/Images/OutliningIndicators/InBlock.gif)
782
return connection;
783![](/Images/OutliningIndicators/InBlock.gif)
784
}
785![](/Images/OutliningIndicators/InBlock.gif)
786
// 设置此对象的,连接
787![](/Images/OutliningIndicators/InBlock.gif)
788![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public void setConnection(Connection connection)
{
789![](/Images/OutliningIndicators/InBlock.gif)
790
this.connection = connection;
791![](/Images/OutliningIndicators/InBlock.gif)
792
}
793![](/Images/OutliningIndicators/InBlock.gif)
794
// 获得对象连接是否忙
795![](/Images/OutliningIndicators/InBlock.gif)
796![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public boolean isBusy()
{
797![](/Images/OutliningIndicators/InBlock.gif)
798
return busy;
799![](/Images/OutliningIndicators/InBlock.gif)
800
}
801![](/Images/OutliningIndicators/InBlock.gif)
802
// 设置对象的连接正在忙
803![](/Images/OutliningIndicators/InBlock.gif)
804![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public void setBusy(boolean busy)
{
805![](/Images/OutliningIndicators/InBlock.gif)
806
this.busy = busy;
807![](/Images/OutliningIndicators/InBlock.gif)
808
}
809![](/Images/OutliningIndicators/InBlock.gif)
810
}
811![](/Images/OutliningIndicators/InBlock.gif)
812
}