For code instructions, references, and runtime environments, see series of articles (V)
/*
* Dbconnectionmanager. Java
* Created on 2005-1-29
*/
Package dB;
Import java. Io .*;
Import java. SQL .*;
Import java. util .*;
Import org. Apache. log4j. Logger;
// Import org. Apache. log4j. propertyconfigurator;
/**
* Management class dbconnectionmanager supports connection to one or more databases defined by attribute files
* Pool access. The client program can call the getinstance () method to access the unique instance of this class.
*
* @ Author yewberry
*/
Public class dbconnectionmanager {
Private Static dbconnectionmanager instance; // unique instance
Private Static int clients;
Private vector drivers = new vector ();
// Private printwriter log;
Private hashtable pools = new hashtable ();
Private Static logger log;
Static {
Try {
Log = logger. getlogger (dbconnectionmanager. Class. getname ());
Log.info ("log4j log class loaded successfully .");
// Specify the location of the log4j. properties File
// Propertyconfigurator. Configure ("C: // test // log4j. properties ");
} Catch (noclassdeffounderror ee ){
System. Out. println ("log4j log class loading failed. ");
}
}
/**
* A unique instance is returned. If this method is called for the first time, an instance is created.
*
* @ Return dbconnectionmanager: unique instance
*/
Static synchronized public dbconnectionmanager getinstance (){
If (instance = NULL ){
Instance = new dbconnectionmanager ();
}
Clients ++;
Return instance;
}
/**
* The construction function is private to prevent other objects from creating instances of this class.
*/
Private dbconnectionmanager (){
Init ();
}
/**
* Return the connection object to the connection pool specified by the name.
*
* @ Param name: name of the Connection Pool defined in the property File
* @ Param con connection object
*/
Public void freeconnection (string name, connection con ){
Dbconnectionpool pool = (dbconnectionpool) pools. Get (name );
If (pool! = NULL ){
Pool. freeconnection (CON );
}
}
/**
* Obtain an available (idle) connection. If there is no available connection, and the number of existing connections is less than the maximum number of connections
* Limit, a new connection is created and returned.
*
* @ Param name: name of the Connection Pool defined in the property File
* @ Return connection available connection or null
*/
Public connection getconnection (string name ){
Dbconnectionpool pool = (dbconnectionpool) pools. Get (name );
If (pool! = NULL ){
Return pool. getconnection ();
}
Return NULL;
}
/**
* Obtain an available connection. If no available connection is available and the number of existing connections is smaller than the maximum number of connections,
* A new connection is created and returned. Otherwise, wait for other threads to release the connection within the specified time.
*
* @ Param name connection pool name
* @ Param time the wait time in milliseconds
* @ Return connection available connection or null
*/
Public connection getconnection (string name, long time ){
Dbconnectionpool pool = (dbconnectionpool) pools. Get (name );
If (pool! = NULL ){
Return pool. getconnection (time );
}
Return NULL;
}
/**
* Close all connections and cancel the registration of the driver.
*/
Public synchronized void release (){
// Wait until the last client program is called
If (-- clients! = 0 ){
Return;
}
Enumeration allpools = pools. Elements ();
While (allpools. hasmoreelements ()){
Dbconnectionpool pool = (dbconnectionpool) allpools. nextelement ();
Pool. Release ();
}
Enumeration alldrivers = drivers. Elements ();
While (alldrivers. hasmoreelements ()){
Driver driver = (driver) alldrivers. nextelement ();
Try {
Drivermanager. deregisterdriver (driver );
If (log. isinfoenabled ()){
Log.info ("revoking the JDBC driver" +
Driver. getclass (). getname () + "registration. ");
}
// Log ("revoking the JDBC driver" + driver. getclass (). getname () + "registration ///");
} Catch (sqlexception e ){
If (log. isinfoenabled ()){
Log.info ("Registration of the following JDBC drivers cannot be revoked:" +
Driver. getclass (). getname (), e );
}
// Log (E, "Registration of the following JDBC driver cannot be revoked:" + driver. getclass (). getname ());
}
}
}
/**
* The read attribute is initialized.
*/
Private void Init (){
Inputstream is = getclass (). getresourceasstream ("/DB. properties ");
Properties dbprops = new properties ();
Try {
Dbprops. Load (is );
// List all elements in dbprops
// Dbprops. List (system. Out );
} Catch (exception e ){
System. Err. println ("attribute files cannot be read. "+
"Make sure that dB. properties is in the path specified by classpath. ");
Return;
}
/*
String logfile = dbprops. getproperty ("logfile", "dbconnectionmanager. log ");
Try {
// Log = new printwriter (New filewriter (logfile, true), true );
} Catch (ioexception e ){
System. Err. println ("log file cannot be opened:" + logfile );
// Log = new printwriter (system. Err );
}
*/
Loaddrivers (dbprops );
Createpools (dbprops );
}
/**
* Load and register all JDBC drivers
*
* @ Param props attributes
*/
Private void loaddrivers (properties props ){
String driverclasses = props. getproperty ("drivers ");
Stringtokenizer ST = new stringtokenizer (driverclasses );
While (St. hasmoreelements ()){
String driverclassname = ST. nexttoken (). Trim ();
Try {
Driver driver = (driver)
Class. forname (driverclassname). newinstance ();
Drivermanager. registerdriver (driver );
Drivers. addelement (driver );
// System. Out. println ("successfully registered JDBC driver:" + driverclassname );
If (log. isinfoenabled ()){
Log.info ("successfully registered JDBC driver:" + driverclassname );
}
// Log ("successfully registered JDBC driver //" + driverclassname );
} Catch (exception e ){
// System. Out. println ("unable to register JDBC driver:" + driverclassname );
If (log. isinfoenabled ()){
Log.info ("unable to register JDBC driver:" +
Driverclassname, e );
}
// Log ("unable to register JDBC driver:" +
// Driverclassname + ", error:" + E );
}
}
}
/**
* Create a connection pool instance based on the specified attributes.
*
* @ Param props connection pool attributes
*/
Private void createpools (properties props ){
Enumeration propnames = props. propertynames ();
While (propnames. hasmoreelements ()){
String name = (string) propnames. nextelement ();
If (name. endswith (". url ")){
String poolname = Name. substring (0, name. lastindexof ("."));
String url = props. getproperty (poolname + ". url ");
If (url = NULL ){
// System. Out. println ("not specified for connection pool" + poolname + "url ");
If (log. isinfoenabled ()){
Log.info ("not specified for connection pool" + poolname + "url ");
}
// Log ("not specified for connection pool" + poolname + "url ");
Continue;
}
String user = props. getproperty (poolname + ". User ");
String Password = props. getproperty (poolname + ". Password ");
String maxconn = props. getproperty (poolname + ". maxconn", "0 ");
Int Max;
Try {
Max = integer. valueof (maxconn). intvalue ();
} Catch (numberformatexception e ){
// System. Out. println ("Maximum number of wrong connections limit:" +
// Maxconn + ". Connection Pool:" + poolname );
If (log. isinfoenabled ()){
Log.info ("Maximum number of wrong connections:" + maxconn +
". Connection Pool:" + poolname );
}
// Log ("Maximum number of wrong connections limit:" + maxconn + ". Connection Pool:" + poolname );
Max = 0;
}
Dbconnectionpool =
New dbconnectionpool (poolname, URL, user, password, max );
Pools. Put (poolname, pool );
// System. Out. println ("successfully created connection pool" + poolname );
// System. Out. println (pools. tostring ());
If (log. isinfoenabled ()){
Log.info ("successfully created connection pool" + poolname );
}
// Log ("successfully created connection pool" + poolname );
}
}
}
}