我测试的环境是:WindowsXP、eclipse3.2、jdk1.6、dom4j1.6.1.jar
其中dom4j1.6.1.jar可以在本人资源库中下载
数据库连接池:说白了就是先建立一堆数据库连接放到集合里面,在用的时候到集合里面中取一个,用完之后放入到连接池中。因此在建立连接池时要通过某个东西来区别,那些正在别使用,那些是空闲连接。
package com.zony.base.database;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Enumeration;
import java.util.Hashtable;
import com.zony.base.Globals;
/**
* 一个数据库连接池
* 连接池中的连接通过键值对保存HashTable:键是:Y(N)+System.currentTimeMillis()
* 值是:Connection
*
* 获取连接时,先从池中判断取出一个有用连接Y + System.currentTimeMillis()
* 以键值对的形式返回,并池中的该连接删除,新增加一个连接
* 该连接的键是将原连接键中的Y换成N, 以表示该连接上被占用状态
* 用完连接之后,将其以键值对的形式返回,返回之前,改变键值对中的键N为Y,
* 然后查找并删除池中被占用的该连接,添加现在可用的连接
*
* 如:
*
* 开始con =null 池中Y1352900127421
* 取出后con = Y1352900127421 池中N1352900127421
*
* 用完后con = Y1352900127421 通过键N1352900127421删除池中的连接,添加Y1352900127421
*
* 之后con =null 池中Y1352900127421
*
*/
public class ConnectionManager_pool {
private static String drivername ;//数据库驱动
private static String url ; //数据库连接路径
private static String username ; //数据库名称
private static String password ; //数据库密码
private static int minCon ; //连接池中最小连接数量
private static int maxCon ; //连接池中最大连接数量
//Hashtable是一个线程安全的集合,conlist的键值以N开头则是占用状态,以Y开头则是空闲状态
public static Hashtable<String,Connection> conlist = new Hashtable<String,Connection>();//可用连接数量
private ConnectionManager_pool(){//获取数据量连接所需参数
drivername = Globals.getProperty("database.defaultProvider.driver");
url = Globals.getProperty("database.defaultProvider.serverURL");
username = Globals.getProperty("database.defaultProvider.username");
password = Globals.getProperty("database.defaultProvider.password");
minCon = Integer.parseInt(Globals.getProperty("database.defaultProvider.minConnections"));
maxCon = Integer.parseInt(Globals.getProperty("database.defaultProvider.maxConnections"));
}
/**
* 在程序启动时,先创建连接池,开始为最小连接数minCon
*/
public static void init(){
new ConnectionManager_pool();//获取数据库连接所需的所有参数
for(int i=1 ; i<=minCon ; i++){
conlist.put("Y"+System.currentTimeMillis(),createConnection());//初始化的时给连接池建立3个连接
}
}
//建立数据库连接
private static Connection createConnection(){
Connection con = null;
try{
Class.forName(drivername);
con = DriverManager.getConnection(url,username,password);
}catch (ClassNotFoundException se) {
se.printStackTrace();
} catch (SQLException se){
se.printStackTrace();
}
return con;
}
/**
* 从数据库连接池中取出一个可用的数据库连接,
* 如果连接池中没有可用连接,则在数据库最大连接数内重新创建数据库连接
*/
public static Object[] getConnection(){
Object[] keycon = new Object[2];
Enumeration<String> e = conlist.keys();
while (e.hasMoreElements()) {
if(e.nextElement().startsWith("Y")){//如果是可用的数据库连接
keycon[0] = e.nextElement();
keycon[1] = conlist.get(e.nextElement());//连接被占用
conlist.remove(keycon[0]);//连接池中先删除被占用连接
conlist.put("N"+keycon[0].toString().substring(1), (Connection)keycon[1]);//添加被占用的连接
return keycon;
}
}
//如果连接池中没有可用连接,则在数据库最大连接数内重新创建数据库连接
if(keycon[0].toString().length()<1&&conlist.size()<=maxCon){
keycon[0] = "Y" + System.currentTimeMillis();
keycon[1] = createConnection();
//将新创建的数据库连接放入到连接池中,此时它是被占用状态
conlist.put("N"+keycon[0].toString().substring(1), (Connection)keycon[1]);
}
return keycon;
}
/**
* 将使用完的数据库连接放入到连接池中
* @param con 被使用完成的数据库连接
*/
public static void setConnection(Object[] keycon){
String key = keycon[0].toString().substring(1);//没有状态的key
Connection con = (Connection)keycon[1];
try {
if(con!=null&&!con.isClosed()){//该连接是可用连接
synchronized(conlist) {//同步连接池
conlist.remove("N"+key);//删除被占用的连接
conlist.put("Y"+key,con);//将已经被使用完的可用连接添加到连接池中
}
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}