要下班了,先把代码贴上来,明天有时间来加说明。
package com;
import java.io.Serializable;
public class ConnectionParam implements Serializable {
private String driver; // 数据库驱动程序
private String url; // 数据连接的URL
private String user; // 数据库用户名
private String password; // 数据库密码
private int minConnection = 0; // 初始化连接数
private int maxConnection = 50; // 最大连接数
private long timeoutValue = 600000;// 连接的最大空闲时间
private long waitTime = 30000; // 取连接的时候如果没有可用连接最大的等待时间
public ConnectionParam(String driver, String url, String user,
String password) {
super();
this.driver = driver;
this.password = password;
this.url = url;
this.user = user;
}
public String getDriver() {
return driver;
}
public void setDriver(String driver) {
this.driver = driver;
}
public int getMaxConnection() {
return maxConnection;
}
public void setMaxConnection(int maxConnection) {
this.maxConnection = maxConnection;
}
public int getMinConnection() {
return minConnection;
}
public void setMinConnection(int minConnection) {
this.minConnection = minConnection;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public long getTimeoutValue() {
return timeoutValue;
}
public void setTimeoutValue(long timeoutValue) {
this.timeoutValue = timeoutValue;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getUser() {
return user;
}
public void setUser(String user) {
this.user = user;
}
public long getWaitTime() {
return waitTime;
}
public void setWaitTime(long waitTime) {
this.waitTime = waitTime;
}
}
DataSourceImpl类:
package com;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import javax.sql.DataSource;
public class DataSourceImpl implements DataSource {
private ConnectionParam param ;
private Connection conn ;
public void initConnection(){
try{
Class.forName(param.getDriver());
conn = DriverManager.getConnection(param.getUrl(),param.getUser(),param.getPassword());
}catch(Exception e){}
}
public void stop() {
}
public void close() {
}
public DataSourceImpl(ConnectionParam param) {
this.param = param;
}
public Connection getConnection() throws SQLException {
return conn;
}
public Connection getConnection(String username, String password)
throws SQLException {
// TODO Auto-generated method stub
return null;
}
public PrintWriter getLogWriter() throws SQLException {
// TODO Auto-generated method stub
return null;
}
public void setLogWriter(PrintWriter out) throws SQLException {
// TODO Auto-generated method stub
}
public void setLoginTimeout(int seconds) throws SQLException {
// TODO Auto-generated method stub
}
public int getLoginTimeout() throws SQLException {
// TODO Auto-generated method stub
return 0;
}
public Object unwrap(Class arg0) throws SQLException {
// TODO Auto-generated method stub
return null;
}
public boolean isWrapperFor(Class arg0) throws SQLException {
// TODO Auto-generated method stub
return false;
}
}
代理接管连接关闭(Connection.close())的类_Connection:
package com;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.Connection;
import java.sql.SQLException;
public class _Connection implements InvocationHandler {
private final static String CLOSE_METHOD_NAME = "close";
private Connection conn = null;
// 数据库的忙状态
private boolean inUse = false;
// 用户最后一次访问该连接方法的时间
private long lastAccessTime = System.currentTimeMillis();
_Connection(Connection conn, boolean inUse) {
this.conn = conn;
this.inUse = inUse;
}
/** *//**
* Returns the conn.
*
* @return Connection
*/
public Connection getConnection() {
// 返回数据库连接conn的接管类,以便截住close方法
Connection conn2 = (Connection) Proxy.newProxyInstance(conn.getClass()
.getClassLoader(), conn.getClass().getInterfaces(), this);
return conn2;
}
/** *//**
* 该方法真正的关闭了数据库的连接
*
* @throws SQLException
*/
void close() throws SQLException {
// 由于类属性conn是没有被接管的连接,因此一旦调用close方法后就直接关闭连接
conn.close();
}
/** *//**
* Returns the inUse.
*
* @return boolean
*/
public boolean isInUse() {
return inUse;
}
/** *//**
* @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object,
* java.lang.reflect.Method, java.lang.Object)
*/
public Object invoke(Object proxy, Method m, Object[] args)
throws Throwable {
Object obj = null;
// 判断是否调用了close的方法,如果调用close方法则把连接置为无用状态
if (CLOSE_METHOD_NAME.equals(m.getName()))
setInUse(false);
else
obj = m.invoke(conn, args);
// 设置最后一次访问时间,以便及时清除超时的连接
lastAccessTime = System.currentTimeMillis();
return obj;
}
/** *//**
* Returns the lastAccessTime.
*
* @return long
*/
public long getLastAccessTime() {
return lastAccessTime;
}
/** *//**
* Sets the inUse.
*
* @param inUse
* The inUse to set
*/
public void setInUse(boolean inUse) {
this.inUse = inUse;
}
}
连接池管理类ConnectionFactory:
package com;
import java.sql.SQLException;
import java.util.Hashtable;
import javax.naming.NameAlreadyBoundException;
import javax.naming.NameNotFoundException;
import javax.sql.DataSource;
/** *//**
* 连接池类厂,该类常用来保存多个数据源名称合数据库连接池对应的哈希
* @author liusoft
*/
public class ConnectionFactory
{
//该哈希表用来保存数据源名和连接池对象的关系表
static Hashtable connectionPools = null;
static{
connectionPools = new Hashtable(2,0.75F);
}
/** *//**
* 从连接池工厂中获取指定名称对应的连接池对象
* @param dataSource 连接池对象对应的名称
* @return DataSource 返回名称对应的连接池对象
* @throws NameNotFoundException 无法找到指定的连接池
*/
public static DataSource lookup(String dataSource)
throws NameNotFoundException
{
Object ds = null;
ds = connectionPools.get(dataSource);
if(ds == null || !(ds instanceof DataSource))
throw new NameNotFoundException(dataSource);
return (DataSource)ds;
}
/** *//**
* 将指定的名字和数据库连接配置绑定在一起并初始化数据库连接池
* @param name 对应连接池的名称
* @param param 连接池的配置参数,具体请见类ConnectionParam
* @return DataSource 如果绑定成功后返回连接池对象
* @throws NameAlreadyBoundException 一定名字name已经绑定则抛出该异常
* @throws ClassNotFoundException 无法找到连接池的配置中的驱动程序类
* @throws IllegalAccessException 连接池配置中的驱动程序类有误
* @throws InstantiationException 无法实例化驱动程序类
* @throws SQLException 无法正常连接指定的数据库
*/
public static DataSource bind(String name, ConnectionParam param)
throws NameAlreadyBoundException,ClassNotFoundException,
IllegalAccessException,InstantiationException,SQLException
{
DataSourceImpl source = null;
try{
lookup(name);
throw new NameAlreadyBoundException(name);
}catch(NameNotFoundException e){
source = new DataSourceImpl(param);
source.initConnection();
connectionPools.put(name, source);
}
return source;
}
/** *//**
* 重新绑定数据库连接池
* @param name 对应连接池的名称
* @param param 连接池的配置参数,具体请见类ConnectionParam
* @return DataSource 如果绑定成功后返回连接池对象
* @throws NameAlreadyBoundException 一定名字name已经绑定则抛出该异常
* @throws ClassNotFoundException 无法找到连接池的配置中的驱动程序类
* @throws IllegalAccessException 连接池配置中的驱动程序类有误
* @throws InstantiationException 无法实例化驱动程序类
* @throws SQLException 无法正常连接指定的数据库
*/
public static DataSource rebind(String name, ConnectionParam param)
throws NameAlreadyBoundException,ClassNotFoundException,
IllegalAccessException,InstantiationException,SQLException
{
try{
unbind(name);
}catch(Exception e){}
return bind(name, param);
}
/** *//**
* 删除一个数据库连接池对象
* @param name
* @throws NameNotFoundException
*/
public static void unbind(String name) throws NameNotFoundException
{
DataSource dataSource = lookup(name);
if(dataSource instanceof DataSourceImpl){
DataSourceImpl dsi = (DataSourceImpl)dataSource;
try{
dsi.stop();
dsi.close();
}catch(Exception e){
}finally{
dsi = null;
}
}
connectionPools.remove(name);
}
}
测试主类:
package com;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import javax.sql.DataSource;
public class test {
public static void main(String[] args) throws Exception {
String name = "poolA";
String driver = "oracle.jdbc.driver.OracleDriver";
String url = "jdbc:oracle:thin:@127.0.0.1:1521:orcl";
ConnectionParam param = new ConnectionParam(driver, url, "zqbchina",
"password");
param.setMinConnection(1);
param.setMaxConnection(5);
param.setTimeoutValue(20000);
ConnectionFactory.bind(name, param);
System.out.println("bind datasource ok.");
// 以上代码是用来登记一个连接池对象,该操作可以在程序初始化只做一次即可
// 以下开始就是使用者真正需要写的代码
DataSource ds = ConnectionFactory.lookup(name);
String sql = "select name from tablea";
_Connection _conn = null;
try {
for (int i = 0; i < 10; i++) {
Connection conn = ds.getConnection();
_conn = new _Connection(conn,false);
conn = _conn.getConnection();
try {
testSQL(conn, sql);
} finally {
try {
conn.close();
} catch (Exception e) {
}
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
ConnectionFactory.unbind(name);
System.out.println("unbind datasource ok.");
System.exit(0);
}
}
public static void testSQL(Connection conn, String sql) throws Exception {
PreparedStatement ps = conn.prepareStatement(sql);
ResultSet rs = ps.executeQuery();
while (rs.next())
System.out.println(rs.getString(1));
}
}
ok。