??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 閱讀(2176)
評論(0) 編輯 收藏 所屬分類:
java