二、具体实现 DBConnectionManager.java程序清单如下:" s- E1 |7 a* }
001 import java.io.*;) z& ~: [4 Q- o+ [" R
002 import java.sql.*;
; T- r- F* v9 ]0 D) k 003 import java.util.*;! ~2 }/ J/ z, ]# x1 [
004 import java.util.Date;$ H+ e& l; i I' d F) _$ T# N
005
0 v* w0 C1 s! ]+ q 006 /**- `0 }' d4 ^9 y
007 * 管理类DBConnectionManager支持对一个或多个由属性文件定义的数据库连接: C# d) W; _5 Y0 g q& g
008 * 池的访问.客户程序可以调用getInstance()方法访问本类的唯一实例.
* R7 _) k8 @2 S. b0 U* } 009 */
2 z$ z$ o' m) U0 A3 b 010 public class DBConnectionManager {1 T R$ x6 t& f4 w0 n
011 static private DBConnectionManager instance; // 唯一实例2 z& ~, K: e2 ]) r: V4 A
012 static private int clients;
: \$ ]% i0 o* d( C, e 0130 M8 s2 i. G) Y7 z1 K2 [
014 private Vector drivers = new Vector();
9 f% e/ v: X2 C, E( K 015 private PrintWriter log;1 P* D2 e2 C( _/ l
016 private Hashtable pools = new Hashtable();; f y+ R* D3 s8 X: z- @; W# V
0172 Z9 @( k% Z. Z
018 /*** M: ~5 m2 K0 S3 P- Q4 c, ]- W, f2 B
019 * 返回唯一实例.如果是第一次调用此方法,则创建实例
* a. x0 E- s2 f& z 020 *
' h4 q3 y/ q( h3 |1 U% \8 Y5 [- } 021 * @return DBConnectionManager 唯一实例" p+ p" Z% }) a1 T! f
022 */" z) L# ]& v8 o: ]1 w3 s7 K& j" M$ q
023 static synchronized public DBConnectionManager getInstance() {
# }) u7 C; n" j- K' X 024 if (instance == null) {' `2 D8 D* C) p7 B- W
025 instance = new DBConnectionManager();
7 L! x2 U: s& n' s" d" I: S# N k$ W 026 }
: P# z! V9 k& D; F2 c% \/ ` 027 clients++;% d" y0 Y) a6 [' j; O. P3 \, c0 c* W; @
028 return instance;
5 g2 k3 d4 z$ P( |5 J- x 029 }
/ |! i1 Q" O% V+ y 0308 i& f. @, [# u" Z6 E
031 /**
+ ]0 Q$ o2 K5 x- N# ?/ o5 {; Y 032 * 建构函数私有以防止其它对象创建本类实例
* m# H& ^( @) Z) P4 S" x7 O 033 */5 m4 b/ E2 ?- @
034 private DBConnectionManager() {
# o7 c9 T, a6 m( B, ^; C 035 init();; I3 Y) q h P- {8 Y/ s. g
036 }' Q1 ]; y+ S d; N- S; V; I
037
5 H6 N" H4 d' o; L8 V3 ` 038 /**
/ y; [( j& H+ c2 y( z" c' M 039 * 将连接对象返回给由名字指定的连接池
* ~6 |1 ^6 V* R 040 *0 E u* o* q# I: `5 S* C4 G1 A+ G
041 * @param name 在属性文件中定义的连接池名字& o& A/ h0 |% E4 Z0 P P/ o, x& V& q
042 * @param con 连接对象
I: T0 v1 A: |# C& Y) y 043 */" i! X( P$ H1 q8 d0 C
044 public void freeConnection(String name, Connection con) {
' t" ]( f! _& P/ F 045 DBConnectionPool pool = (DBConnectionPool) pools.get(name);
8 H: y: p: @" V0 Y4 n7 u- D 046 if (pool != null) {
; [: p g& [* I9 P& e9 m$ B8 i) p 047 pool.freeConnection(con);, p, X" v2 p {8 \+ m8 I
048 }
7 m c) i2 L5 U3 X/ _ 049 }
- z8 W+ H. a+ s5 { g7 a L 050& f# @! `3 T8 g6 ~1 `& d# _
051 /**
* D8 K( f( {8 H$ W7 Z D 052 * 获得一个可用的(空闲的)连接.如果没有可用连接,且已有连接数小于最大连接数
) a% \6 F- i# D2 I 053 * 限制,则创建并返回新连接
# m9 X8 e% u& W* R( Z 054 *4 R( w! Z5 Q. h
055 * @param name 在属性文件中定义的连接池名字
4 e7 t: l2 O! F 056 * @return Connection 可用连接或null
# g/ l7 I" ^7 p6 C' ^9 y: I 057 */* T" Q5 y( x, F
058 public Connection getConnection(String name) {7 f7 I r: N' k
059 DBConnectionPool pool = (DBConnectionPool) pools.get(name);
' o. T; M; R. @) `# k! }# p7 ] 060 if (pool != null) {) I0 T2 E. S8 u- [
061 return pool.getConnection();
# k4 g0 W* V) y* { 062 }4 O: V) W4 T; V# K, s& n8 n
063 return null;
* |9 m% X/ q/ W( v3 j( D7 o 064 }* [2 @: p( x, Z. }0 b- ^
065
, W4 ~4 H1 i7 v9 Z; i 066 /**
0 f Q8 J0 g$ X) S- @ 067 * 获得一个可用连接.若没有可用连接,且已有连接数小于最大连接数限制,
9 y3 N8 l! S# G Y: W4 L. g* V 068 * 则创建并返回新连接.否则,在指定的时间内等待其它线程释放连接.
2 U: q }7 T4 X# V- B8 L 069 *2 I5 K# [& e1 f' v! F+ p' N9 h
070 * @param name 连接池名字
, B$ m+ t6 O2 V6 P( R; Q1 V2 Q/ r 071 * @param time 以毫秒计的等待时间 O+ _! N9 H) ^
072 * @return Connection 可用连接或null
3 n) K% w; G4 ~! r 073 */6 w* j1 e/ Y' p/ D E! q) E
074 public Connection getConnection(String name, long time) {( n# h9 E; g" J3 D3 T' G
075 DBConnectionPool pool = (DBConnectionPool) pools.get(name);
# @- g! l7 i& u) T5 u$ } 076 if (pool != null) {
: C9 z1 y; U, W% K$ O# r! P 077 return pool.getConnection(time);
8 j1 h/ _6 W( G5 ]' Q5 C! e$ N5 r 078 }
& ?$ h" x: @8 z6 h4 M Y0 X 079 return null;
! ?/ o0 Z3 j9 I9 F* k; K$ Q2 j7 @) A 080 }
9 w5 n0 i: o8 f8 I: @0 c+ R4 c! K( y 081
- s6 u/ b5 N9 _1 n, U4 T 082 /**8 u% k2 @) \& B; V( \1 {
083 * 关闭所有连接,撤销驱动程序的注册
, a& F1 q6 f4 O' X0 | 084 */
3 z2 f L' Y+ ~" C+ c* H 085 public synchronized void release() {* l) P: @* u# @8 R
086 // 等待直到最后一个客户程序调用
, H4 \6 W4 b# a* [% @! o1 l# C8 _7 i 087 if (--clients != 0) {+ [1 e! W' p) x0 f6 W ~4 x* N8 A
088 return;
& ~8 V; C, v, B 089 }. l5 ~5 U* G+ L. d2 U
090
: R3 v* S( G0 B1 N3 B+ C5 k 091 Enumeration allPools = pools.elements();. k- U& G6 Y$ S% q3 U2 ]% X% a
092 while (allPools.hasMoreElements()) {
' D3 d' x3 A: Q9 _ 093 DBConnectionPool pool = (DBConnectionPool) allPools.nextElement();+ Z. R8 m' {4 C) t
094 pool.release();9 C6 a t; ?: `. ?" s( ^' |! o
095 }( s* M! ?# W" s2 j {3 J3 {# ]- n
096 Enumeration allDrivers = drivers.elements();
( I$ C8 y7 l( p( r# R 097 while (allDrivers.hasMoreElements()) {
2 d! {# p8 }" W( H. w 098 Driver driver = (Driver) allDrivers.nextElement();
. m! k3 H% ~; c& m1 {0 V+ ] 099 try {, m% F# s4 u8 P- w4 g' o
100 DriverManager.deregisterDriver(driver);& z ]5 @; [+ `; e- Y
101 log("撤销JDBC驱动程序 " + driver.getClass().getName()+"的注册");
0 ~) I j$ S0 @ 102 }
8 L% }, [6 ~0 \ 103 catch (SQLException e) {! f) o3 A4 e2 a+ ^+ Q R0 l
104 log(e, "无法撤销下列JDBC驱动程序的注册: " + driver.getClass().getName());6 |8 t0 G! m, {
105 }4 x4 I/ t: x2 ^8 }& F
106 }7 w6 K& k, w# R1 B7 j
107 }
- G& j# j- f' H2 x 1087 P" P! H7 D3 Q, J/ a4 f) F
109 /** |