⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 connectionmanager.java

📁 以前写的通用数据库接口
💻 JAVA
字号:
package util.database;


import java.sql.*;
import java.util.*;

/**
 * ConnectionManager
 * 数据库连接的管理类,使用连接池。默认的最小连接数和最大连接数分别为5,10。
 * 如果用户指定的值大于默认值,就采用指定的值
 *
 * @author Michael Zeng
 * @version 1.0 September 18, 2002
 *
 * @todo: 目前还只能支持一个数据库和一个连接池。因为在构造函数中指定了数据库的
 * 各种参数,不是很灵活。下一步采用loadProperty()方法从一个配置文件中直接读取参
 * 数,并且考虑支持多个连接池。
 */
public class ConnectionManager
{
    private static ConnectionManager instance = null;
    private ConnectionPool connPool = null;
    private String driver, url, user, passwd;
    private int minConn = 5, maxConn = 10;
    private final long PERIOD = 20000;  //线程等待的时间20秒
    private final int TRY_TIMES = 5;    //池中没有可用连接时的重试次数

    /**
     * 得到ConnectionManager的一个唯一实例
     *
     * @param _driver 数据库驱动程序
     * @param _url 数据库的地址
     * @param _user 数据库用户名
     * @param _passwd 用户密码
     * @param _minConn 最小支持的连接数目
     * @param _maxConn 最大支持的连接数目
     * @return ConnectionManager 唯一实例
     *
     * @throws Exception
     */
    public static ConnectionManager getInstance(String _driver, String _url, String _user,
            String _passwd, int _minConn, int _maxConn) throws Exception
    {
        if(instance == null)
        {
            instance = new ConnectionManager(_driver, _url, _user, _passwd,
                    _minConn, _maxConn);
        }
        return instance;
    }

    /**
     * 从连接池中得到Conncetion的一个实例
     *
     * @return Connection 连接的实例,出现异常情况时,返回null
     *
     * @throws Exception
     */
    public Connection getConnection() throws Exception
    {
        return this.connPool.getConnection();
    }

    /**
     * 把一个Connection实例返回连接池,如果已经到了池的最大容量,
     * 就把这个连接释放。
     *
     * @param conn 要返回的Connection
     *
     * @throws Exception
     */
    public void freeConncetion(Connection conn) throws Exception
    {
        this.connPool.freeConncetion(conn);
    }

    /**
     * 释放连接池中的所有Connection
     *
     * @throws Exception
     */
    public void close()throws Exception
    {
        this.connPool.release();
    }

    /**
     * 得到连接池的实际大小
     *
     * @return int 连接池的大小
     */
    public int getPoolSize()
    {
        return this.connPool.getPoolSize();
    }

    /**
     * 私有的构造函数
     *
     * @param _driver 数据库驱动程序
     * @param _url 数据库的地址
     * @param _user 数据库用户名
     * @param _passwd 用户密码
     * @param _minConn 最小支持的连接数目
     * @param _maxConn 最大支持的连接数目
     * @return ConnectionManager 实例
     *
     * @throws Exception
     */
    private ConnectionManager(String _driver, String _url, String _user,
                              String _passwd, int _minConn, int _maxConn) throws Exception
    {
        this.driver = _driver;
        this.url = _url;
        this.user = _user;
        this.passwd = _passwd;
        //如果用户指定的值大于默认值,就采用指定的值
        this.minConn = Math.max(this.minConn, _minConn);
        this.maxConn = Math.max(this.maxConn, _maxConn);
        //如果用户指定的min > max,强迫两个值相等
        this.minConn = Math.min(this.minConn, this.maxConn);

        this.connPool = new ConnectionPool();
    }

    /**
     * ConnectionPool
     * inner class
     */
    private class ConnectionPool implements Runnable
    {
        private List pool = null;
        private Thread runner = null;
        private boolean runOver = false;//是否结束线程的标识

        /**
         * 构造函数,初始化连接池中的Connection
         *
         * @throws Exception
         */
        public ConnectionPool() throws Exception
        {
            this.pool = new LinkedList();
            //初始化最小数量的Connection
            for (int i = 0; i < minConn; i++)
            {
                this.pool.add(this.createConnection());
            }
            //启动线程
            runner = new Thread(this);
            runner.start();
        }

        /**
         * 实现Runnable接口的方法。在后台进行周期性的检测,保证连接池中的可用
         * 连接数目不小于最小连接数目
         */
        public void run()
        {
            while (true)
            {
                if(runOver == true) return;

                //当可用连接数目小于最小连接数目,表达式(minConn - pool.size())
                //的结果是大于0的整数,执行循环
                int numOfLack = 0;
                if(this.pool != null)   numOfLack = minConn - pool.size();
                for (int i = 0; i < numOfLack; i++)
                {
                    try{    this.pool.add(this.createConnection()); }
                    catch (Exception ex){}
                }

                try{    Thread.sleep(PERIOD);   }
                catch (InterruptedException ex){}
            }// end of while()
        }

        /**
         * 从连接池中得到Conncetion的一个实例
         *
         * @return Connection 连接的实例,出现异常情况时,返回null
         *
         * @throws Exception
         */
        public synchronized Connection getConnection() throws Exception
        {
            Connection conn = null;
            //进行指定次数的尝试
            for (int i = 0; i < TRY_TIMES; i++)
            {
                if(this.pool.size() > 0)
                {
                    //取得池中的第一个
                    conn = (Connection)this.pool.remove(0);
                    break;
                }
                else
                {
                    //等待半个周期
                    wait(PERIOD / 2);
                }
            }
            //如果经过等待仍然没有可用的连接(某种异常情况),返回null
            if(conn == null)    return null;
            //如果取得的连接不可用,递归调用自己
            if(conn.isClosed()) conn = this.getConnection();
            return conn;
        }

        /**
         * 把一个Connection实例返回连接池,如果已经到了池的最大容量,
         * 就把这个连接释放。
         *
         * @param conn 要返回的Connection
         *
         * @throws Exception
         */
        public synchronized void freeConncetion(Connection conn) throws Exception
        {
            //无效的连接不需要返回池中
            if(conn == null || conn.isClosed()) return;

            if(this.pool.size() < maxConn )
                this.pool.add(conn);
            else
                conn.close();
        }

        /**
         * 释放连接池中的所有Connection
         *
         * @throws Exception
         */
        public synchronized void release()throws Exception
        {
            Connection conn = null;
            for (int i = 0; i < this.pool.size(); i++)
            {
                conn = (Connection)this.pool.get(i);
                conn.close();
            }
            conn = null;
            this.pool = null;
            this.runOver = true; //是否结束线程的标识
        }

        /**
         * 得到连接池的实际大小
         *
         * @return int 连接池的大小
         */
        public int getPoolSize()
        {
            return this.pool.size();
        }

        /**
         * helper方法,建立一个数据库的连接
         *
         * @return Connection 数据库的连接
         * @throws Exception
         */
        private Connection createConnection() throws Exception
        {
            Class.forName(driver);
            return DriverManager.getConnection(url,user, passwd);
        }
    }// inner class ConnectionPool

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -