几种Java数据库连接池实现(三)<1>

package pool;
import java.lang.reflect.*;
import java.sql.*;
/**
*
* 定义数据库连接的代理类
*
*/
public class _Connection implements InvocationHandler {
    // 定义连接
    private Connection conn = null;
    // 定义监控连接创建的语句
    private Statement statRef = null;
    private PreparedStatement prestatRef = null;
    // 是否支持事务标志
    private boolean supportTransaction = false;
    // 数据库的忙状态
    private boolean isFree = false;
    // 最后一次访问时间
    long lastAccessTime = 0;
    // 定义要接管的函数的名字
    String CREATESTATE = "createStatement";
    String CLOSE = "close";
    String PREPARESTATEMENT = "prepareStatement";
    String COMMIT = "commit";
    String ROLLBACK = "rollback";
    /**
    * 构造函数,采用私有,防止被直接创建
    *
    * @param param
    *            连接参数
    */
    private _Connection(ConnectionParam param) { // 记录日志
        try {
            // 创建连接
            Class.forName(param.getDriver()).newInstance();
            conn = DriverManager.getConnection(param.getUrl(), param.getUser(),
                    param.getPassword());
            DatabaseMetaData dm = null;
            dm = conn.getMetaData();
            // 判断是否支持事务
            supportTransaction = dm.supportsTransactions();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /*
    * (non-Javadoc)
    * @see java.lang.reflect.InvocationHandler#invoke
    * (java.lang.Object, java.lang.reflect.Method, java.lang.Object[])
    */
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        Object obj = null;
        // 判断是否调用了close的方法,如果调用close方法则把连接置为无用状态
        if (CLOSE.equals(method.getName())) {
            // 设置不使用标志
            setIsFree(false);
            // 检查是否有后续工作,清除该连接无用资源
            if (statRef != null)
                statRef.close();
            if (prestatRef != null)
                prestatRef.close();
            return null;
        }
        // 判断是使用了createStatement语句
        if (CREATESTATE.equals(method.getName())) {
            obj = method.invoke(conn, args);
            statRef = (Statement) obj;// 记录语句
            return obj;
        }
        // 判断是使用了prepareStatement语句
        if (PREPARESTATEMENT.equals(method.getName())) {
            obj = method.invoke(conn, args);
            prestatRef = (PreparedStatement) obj;
            return obj;
        }
        // 如果不支持事务,就不执行该事物的代码
        if ((COMMIT.equals(method.getName()) || ROLLBACK.equals(method
                .getName()))
                && (!isSupportTransaction()))
            return null;
        obj = method.invoke(conn, args);
        // 设置最后一次访问时间,以便及时清除超时的连接
        lastAccessTime = System.currentTimeMillis();
        return obj;
    }

    /**
    * 创建连接的工厂,只能让工厂调用
    * @param factory
    *            要调用工厂,并且一定被正确初始化
    * @param param
    *            连接参数
    * @return 连接
    *
    */
    public static _Connection getConnection(ConnectionFactory factory,
            ConnectionParam param) {
        if (factory.isCreate()) {// 判断是否正确初始化的工厂
            _Connection _conn = new _Connection(param);
            return _conn;
        } else {
            return null;
        }
    }
    public Connection getFreeConnection() {
        // 返回数据库连接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();
    }
    public void setIsFree(boolean value) {
        isFree = value;
    }
    public boolean isFree() {
        return isFree;
    }
    /**
    *
    * 判断是否支持事务
    *
    * @return boolean
    *
    */
    public boolean isSupportTransaction() {
        return supportTransaction;
    }
}

package pool;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Iterator;
import java.util.LinkedHashSet;
public class ConnectionFactory {
    private static ConnectionFactory m_instance = null;
    // 在使用的连接池
    private LinkedHashSet<_Connection> ConnectionPool = null;
    // 空闲连接池
    private LinkedHashSet<_Connection> FreeConnectionPool = null;
    // 最大连接数
    private int MaxConnectionCount = 4;
    // 最小连接数
    private int MinConnectionCount = 2;
    // 当前连接数
    private int current_conn_count = 0;
    // 连接参数
    private ConnectionParam connparam = null;
    // 是否创建工厂的标志
    private boolean isflag = false;
    // 是否支持事务
    private boolean supportTransaction = false;
    // 定义管理策略
    private int ManageType = 0;
    private ConnectionFactory() {
        ConnectionPool = new LinkedHashSet<_Connection>();
        FreeConnectionPool = new LinkedHashSet<_Connection>();
    }
    /**
    *
    * 使用指定的参数创建一个连接池
    *
    */
    public ConnectionFactory(ConnectionParam param, FactoryParam fparam)
            throws SQLException {
        // 不允许参数为空
        if ((param == null) || (fparam == null))
            throw new SQLException("ConnectionParam和FactoryParam不能为空");
        if (m_instance == null) {
            synchronized (ConnectionFactory.class) {
                if (m_instance == null) {
                    // new instance
                    // 参数定制
                    m_instance = new ConnectionFactory();
                    m_instance.connparam = param;
                    m_instance.MaxConnectionCount = fparam.getMaxConn();
                    m_instance.MinConnectionCount = fparam.getMinConn();
                    m_instance.ManageType = fparam.getType();
                    m_instance.isflag = true;
                    // 初始化,创建MinConnectionCount个连接
                    System.out.println("connection factory 创建!");
                    try {
                        for (int i = 0; i < m_instance.MinConnectionCount; i++) {
                            _Connection _conn = _Connection.getConnection(
                                    m_instance, m_instance.connparam);
                            if (_conn == null)
                                continue;
                            System.out.println("connection创建");
                            m_instance.FreeConnectionPool.add(_conn);// 加入空闲连接池
                            m_instance.current_conn_count++;
                            // 标志是否支持事务
                            m_instance.supportTransaction = _conn
                                    .isSupportTransaction();
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    // 根据策略判断是否需要查询
                    if (m_instance.ManageType != 0) {
                        Thread t = new Thread(
                                new FactoryMangeThread(m_instance));
                        t.start();
                    }
                }
            }
        }
    }

    /**
    *
    * 标志工厂是否已经创建
    *
    * @return boolean
    *
    */
    public boolean isCreate() {
        return m_instance.isflag;
    }

    /**
    *
    * 从连接池中取一个空闲的连接
    *
    * @return Connection
    *
    * @throws SQLException
    *
    */
    public synchronized Connection getFreeConnection() throws SQLException {
        Connection conn = null;
        // 获取空闲连接
        Iterator iter = m_instance.FreeConnectionPool.iterator();
        while (iter.hasNext()) {
            _Connection _conn = (_Connection) iter.next();
            // 找到未用连接
            if (!_conn.isFree()) {
                conn = _conn.getFreeConnection();
                _conn.setIsFree(true);
                // 移出空闲区
                m_instance.FreeConnectionPool.remove(_conn);
                // 加入连接池
                m_instance.ConnectionPool.add(_conn);
                break;
            }
        }
        // 检查空闲池是否为空
        if (m_instance.FreeConnectionPool.isEmpty()) {
            // 再检查是否能够分配
            if (m_instance.current_conn_count < m_instance.MaxConnectionCount) {
                // 新建连接到空闲连接池
                int newcount = 0;
                // 取得要建立的数目
                if (m_instance.MaxConnectionCount
                        - m_instance.current_conn_count >= m_instance.MinConnectionCount) {
                    newcount = m_instance.MinConnectionCount;
                } else {
                    newcount = m_instance.MaxConnectionCount
                            - m_instance.current_conn_count;
                }
                // 创建连接
                for (int i = 0; i < newcount; i++) {
                    _Connection _conn = _Connection.getConnection(m_instance,
                            m_instance.connparam);
                    m_instance.FreeConnectionPool.add(_conn);
                    m_instance.current_conn_count++;
                }
            } else {// 如果不能新建,检查是否有已经归还的连接
                iter = m_instance.ConnectionPool.iterator();
                while (iter.hasNext()) {
                    _Connection _conn = (_Connection) iter.next();
                    if (!_conn.isFree()) {
                        conn = _conn.getFreeConnection();
                        _conn.setIsFree(false);
                        m_instance.ConnectionPool.remove(_conn);
                        m_instance.FreeConnectionPool.add(_conn);
                        break;
                    }
                }
            }
        }// if (FreeConnectionPool.isEmpty())
        // 再次检查是否能分配连接
        if (conn == null) {
            iter = m_instance.FreeConnectionPool.iterator();
            while (iter.hasNext()) {
                _Connection _conn = (_Connection) iter.next();
                if (!_conn.isFree()) {
                    conn = _conn.getFreeConnection();
                    _conn.setIsFree(true);
                    m_instance.FreeConnectionPool.remove(_conn);
                    m_instance.ConnectionPool.add(_conn);
                    break;
                }
            }
            if (conn == null)// 如果不能则说明无连接可用
                throw new SQLException("没有可用的数据库连接");
        }
        System.out.println("get connection");
        return conn;
    }

    /**
    *
    * 关闭该连接池中的所有数据库连接
    *
    * @throws SQLException
    *
    */
    public synchronized void close() throws SQLException {
        this.isflag = false;
        SQLException excp = null;
        // 关闭空闲池
        Iterator iter = m_instance.FreeConnectionPool.iterator();
        while (iter.hasNext()) {
            try {
                ((_Connection) iter.next()).close();
                System.out.println("close connection:free");
                m_instance.current_conn_count--;
            } catch (Exception e) {
                if (e instanceof SQLException)
                    excp = (SQLException) e;
            }
        }
        // 关闭在使用的连接池
        iter = m_instance.ConnectionPool.iterator();
        while (iter.hasNext()) {
            try {
                ((_Connection) iter.next()).close();
                System.out.println("close connection:inused");
                m_instance.current_conn_count--;
            } catch (Exception e) {
                if (e instanceof SQLException)
                    excp = (SQLException) e;
            }
        }
        if (excp != null)
            throw excp;
    }

    /**
    *
    * 返回是否支持事务
    *
    * @return boolean
    *
    */
    public boolean isSupportTransaction() {
        return m_instance.supportTransaction;
    }

    /**
    *
    * 连接池调度管理
    *
    *
    *
    */
    public void schedule() {
        //Connection conn = null;
        // 再检查是否能够分配
        Iterator iter = null;
        // 检查是否有已经归还的连接
        iter = m_instance.ConnectionPool.iterator();
        while (iter.hasNext()) {
            _Connection _conn = (_Connection) iter.next();
            if (!_conn.isFree()) {
                //conn = _conn.getFreeConnection();
                _conn.setIsFree(false);
                m_instance.ConnectionPool.remove(_conn);
                m_instance.FreeConnectionPool.add(_conn);
                break;
            }
        }

        if (m_instance.current_conn_count < m_instance.MaxConnectionCount) {
            // 新建连接到空闲连接池
            int newcount = 0;
            // 取得要建立的数目
            if (m_instance.MaxConnectionCount - m_instance.current_conn_count >= m_instance.MinConnectionCount) {
                newcount = m_instance.MinConnectionCount;
            } else {
                newcount = m_instance.MaxConnectionCount
                        - m_instance.current_conn_count;
            }
            // 创建连接
            for (int i = 0; i < newcount; i++) {
                _Connection _conn = _Connection.getConnection(m_instance,
                        m_instance.connparam);
                m_instance.FreeConnectionPool.add(_conn);
                m_instance.current_conn_count++;
            }
        }
    }
}

package pool;

import java.io.Serializable;

public class ConnectionParam implements Serializable {
    private static final long serialVersionUID = 1L;

    private String driver; // 数据库驱动程序

    private String url; // 数据连接的URL

    private String user; // 数据库用户名

    private String password; // 数据库密码

    /**
    *
    * 唯一的构造函数,需要指定连接的四个必要参数
    *
    * @param driver
    *            数据驱动
    *
    * @param url
    *            数据库连接url
    *
    * @param user
    *            用户名
    *
    * @param password
    *            密码
    *
    */
    public ConnectionParam(String driver, String url, String user,
            String password) {
        this.driver = driver;
        this.url = url;
        this.user = user;
        this.password = password;
    }

    public String getDriver() {
        return driver;
    }

    public String getPassword() {
        return password;
    }

    public String getUrl() {
        return url;
    }

    public String getUser() {
        return user;
    }

    public void setDriver(String driver) {
        this.driver = driver;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public void setUser(String user) {
        this.user = user;
    }

    /**
    *
    * @see java.lang.Object#clone()
    *
    */
    public Object clone() {
        ConnectionParam param = new ConnectionParam(driver, url, user, password);
        return param;
    }

    /**
    *
    * @see java.lang.Object#equals(java.lang.Object)
    *
    */
    public boolean equals(Object obj) {
        if (obj instanceof ConnectionParam) {
            ConnectionParam param = (ConnectionParam) obj;
            return ((driver.compareToIgnoreCase(param.getDriver()) == 0)
                    && (url.compareToIgnoreCase(param.getUrl()) == 0)
                    && (user.compareToIgnoreCase(param.getUser()) == 0) && (password
                    .compareToIgnoreCase(param.getPassword()) == 0));
        }
        return false;
    }
}

猜你喜欢

转载自wush121.iteye.com/blog/1489101