package db;
import java.io. * ;
import java.sql. * ;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util. * ;
public class DBConnectionManager
... {
class DBConnectionPool
...{
private int checkedOut;
private Vector freeConnections;
private Vector allcreateConnections;
private int maxConn;
private int contimeout;
private String name;
private String password;
private String URL;
private String user;
private int connum;
public synchronized void freeConnection(Connection con)
...{
freeConnections.addElement(con);
checkedOut--;
log("在线连接数减少到:" + checkedOut);
notifyAll();
}
public synchronized Connection getConnection()
...{
Connection con = null;
log("空闲连接数为(连接前):" +
freeConnections.size());
if(freeConnections.size() > 0)
...{
con = (Connection)freeConnections.firstElement();
freeConnections.removeElementAt(0);
try
...{
if(con.isClosed())
...{
connum--;
log("从连接池" + name + "删除一
个无效连接,共有连接:" + connum);
con = getConnection();
}
}
catch(SQLException e)
...{
connum--;
log("从连接池" + name + "删除一个无
效连接,共有连接:" + connum);
con = getConnection();
}
} else
if(maxConn == 0 || checkedOut < maxConn)
con = newConnection();
else
if(checkedOut == maxConn)
try
...{
wait(contimeout);
release();
checkedOut = 0;
con = getConnection();
}
catch(InterruptedException interruptedexception) ...{ }
if(con != null)
checkedOut++;
return con;
}
public synchronized Connection getConnection(long timeout)
...{
long startTime = (new Date()).getTime();
Connection con;
while((con = getConnection()) == null)
...{
try
...{
wait(timeout);
}
catch(InterruptedException interruptedexception) ...{ }
if((new Date()).getTime() - startTime >= timeout)
return null;
}
return con;
}
public synchronized void release()
...{
for(Enumeration allConnections = allcreateConnections.elements();
allConnections.hasMoreElements();)
...{
Connection con = (Connection)allConnections.nextElement();
try
...{
con.close();
connum--;
log("关闭连接池" + name + "中的一
个连接,共有连接:" + connum);
}
catch(SQLException e)
...{
log(e, "无法关闭连接池" + name +
"中的连接");
}
}
freeConnections.removeAllElements();
allcreateConnections.removeAllElements();
}
private Connection newConnection()
...{
Connection con = null;
try
...{
if(user == null)
con = DriverManager.getConnection(URL);
else
con = DriverManager.getConnection(URL, user, password);
allcreateConnections.addElement(con);
connum++;
log("连接池" + name + "创建一个新的
连接,共有连接:" + connum);
log("空闲连接数为(创建后):" +
freeConnections.size());
}
catch(SQLException e)
...{
log(e, "无法创建下列URL的连接: " + URL);
return null;
}
return con;
}
public DBConnectionPool(String name, String URL, String user, String password, int
maxConn, int contimeout)
...{
freeConnections = new Vector();
allcreateConnections = new Vector();
connum = 0;
this.name = name;
this.URL = URL;
this.user = user;
this.password = password;
this.maxConn = maxConn;
this.contimeout = contimeout;
}
}
private static DBConnectionManager instance;
private static int clients;
private Vector drivers;
private PrintWriter log;
private Hashtable pools;
private String logFile;
private String strLogTime;
private DBConnectionManager()
...{
drivers = new Vector();
pools = new Hashtable();
init();
}
private void createPools(Properties props)
...{
for(Enumeration propNames = props.propertyNames(); 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)
...{
log("没有为连接池" + poolName + "指
定URL");
} else
...{
String user = props.getProperty(poolName + ".user");
String password = props.getProperty(poolName + ".password");
String maxconn = props.getProperty(poolName + ".maxconn", "0");
String contimeout = props.getProperty(poolName + ".timeout", "0");
int contime = 0;
int max;
try
...{
max = Integer.valueOf(maxconn).intValue();
contime = Integer.valueOf(contimeout).intValue();
}
catch(NumberFormatException e)
...{
log("错误的最大连接数限制: "
+ maxconn + " .连接池: " + poolName);
max = 0;
contime = 0;
}
DBConnectionPool pool = new DBConnectionPool(poolName, url, user,
password, max, contime);
pools.put(poolName, pool);
log("成功创建连接池" + poolName);
}
}
}
}
public void freeConnection(String name, Connection con)
...{
DBConnectionPool pool = (DBConnectionPool)pools.get(name);
if(pool != null)
pool.freeConnection(con);
}
public Connection getConnection(String name)
...{
DBConnectionPool pool = (DBConnectionPool)pools.get(name);
if(pool != null)
return pool.getConnection();
else
return null;
}
public Connection getConnection(String name, long time)
...{
DBConnectionPool pool = (DBConnectionPool)pools.get(name);
if(pool != null)
return pool.getConnection(time);
else
return null;
}
public static synchronized DBConnectionManager getInstance()
...{
if(instance == null)
instance = new DBConnectionManager();
clients++;
return instance;
}
private void init()
...{
java.io.InputStream is = getClass().getResourceAsStream("/db/db.properties");
Properties dbProps = new Properties();
try
...{
dbProps.load(is);
}
catch(Exception e)
...{
System.err.println("不能读取属性文件. 请
确保db.properties在CLASSPATH指定的路径中");
return;
}
logFile = dbProps.getProperty("logfile", "DBConnectionManager.log");
loadDrivers(dbProps);
createPools(dbProps);
}
private void loadDrivers(Properties props)
...{
String driverClasses = props.getProperty("drivers");
for(StringTokenizer st = new StringTokenizer(driverClasses); st.hasMoreElements();)
...{
String driverClassName = st.nextToken().trim();
try
...{
Driver driver = (Driver)Class.forName(driverClassName).newInstance();
DriverManager.registerDriver(driver);
drivers.addElement(driver);
log("成功注册JDBC驱动程序" +
driverClassName);
}
catch(Exception e)
...{
log("无法注册JDBC驱动程序: " +
driverClassName + ", 错误: " + e);
}
}
}
private void setLogFile()
...{
try
...{
DateFormat dflog = new SimpleDateFormat("yyyyMMdd");
String strDate = dflog.format(new Date());
DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
strLogTime = df.format(new Date());
int pos = logFile.indexOf(".");
String strFullLogFile;
if(pos == -1)
...{
strFullLogFile = logFile + strDate + ".log";
} else
...{
String logFileName = logFile.substring(0, pos) + strDate;
String logFileType = logFile.substring(pos, logFile.length());
strFullLogFile = logFileName + logFileType;
}
log = new PrintWriter(new FileWriter(strFullLogFile, true), true);
}
catch(IOException e)
...{
System.err.println("无法打开日志文件: " +
logFile);
log = new PrintWriter(System.err);
}
}
private void log(String msg)
...{
setLogFile();
log.println(strLogTime + ": " + msg);
}
private void log(Throwable e, String msg)
...{
setLogFile();
log.println(strLogTime + ": " + msg);
e.printStackTrace(log);
}
public synchronized void release()
...{
if(--clients != 0)
return;
DBConnectionPool pool;
for(Enumeration allPools = pools.elements(); allPools.hasMoreElements();
pool.release())
pool = (DBConnectionPool)allPools.nextElement();
for(Enumeration allDrivers = drivers.elements(); allDrivers.hasMoreElements();)
...{
Driver driver = (Driver)allDrivers.nextElement();
try
...{
DriverManager.deregisterDriver(driver);
log("撤销JDBC驱动程序 " + driver.getClass().getName
() + "的注册");
}
catch(SQLException e)
...{
log(e, "无法撤销下列JDBC驱动
程序的注册: " + driver.getClass().getName());
}
}
}
}
别忘了,还要有一个外部的配制文件(db.properties):
drivers=oracle.jdbc.driver.OracleDriver
logfile=C://DBConnectionManager.log
iwh.url=jdbc:oracle:thin:@127.0.0.1:1521:111
iwh.user=111
iwh.password=111
iwh.maxconn=150
iwh.timeout=3000