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

📄 dbconnectionmanager.java

📁 一个基于java的记事本
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
        public synchronized void release() {
            Enumeration allConnections = freeConnections.elements();
            while (allConnections.hasMoreElements()) { //freeConnections对象存在
                Connection con = (Connection) allConnections.nextElement(); //取出所有的数组
                try {
                    con.close(); //尝试关闭
                    Debug.writeLog("关闭连接池" + name + "中的一个连接");
                }
                catch (SQLException e) {
                    Debug.writeLog("无法关闭连接池" + name + "中的连接");
                    e.printStackTrace(System.out);
                }
            }
            freeConnections.removeAllElements(); //清空
        }
    }

    /**
     * *****************************************************************
     * 建构函数私有以防止其它对象创建本类实例
     * 其它对象能够调用其静态方法(也称为类方法)获得该唯一实例的引用
     * DBConnectionManager类的建构函数是私有的,这是为了避免其它对象创建该类的实例。
     */
    private DBConnectionManager() {
        init();
    }

    /**
     *
     * @param props 连接池属性
     */
    private void createPools(Properties props) {
        Enumeration propNames = props.propertyNames(); //创建枚举对象----该对象可以想象为一个元素系列,逐次调用其nextElement()方法将顺序返回各元素
        while (propNames.hasMoreElements()) { //如果有枚举对象存在
            String name = (String) propNames.nextElement(); //取出值格式为字符串
            Debug.writeLog("createPools(Properties), name is:  " + name); //3、logPath 将路径名写入日志
            /**
             * 在其中搜索名字以“.url”结尾的属性
             * 对于每一个符合条件的属性,先提取其连接池名字部分,进而读取所有属于该连接池的属性
             */
            if (name.endsWith(".url")) {
                Debug.writeLog("createPools(Properties), name end with url"); //5
                String poolName = name.substring(0, name.lastIndexOf(".")); //取出“.”之前的字符串(连接池的名字)
                String url = props.getProperty(poolName + ".url"); //4、Connection.url 取得URL
                Debug.writeLog("createPools(Properties), url is " + url); //6、jdbc:mysql://127.0.0.1:3306/nt 写入数据库的url"jdbc:mysql://127.0.0.1:3306/数据名"
                if (url == null) { //如果URL为空,写入日志显示没有找到指定的URL
                    Debug.writeLog("没有为连接池" + poolName + "指定URL");
                    continue; //跳出本次循环
                }
                String user = props.getProperty(poolName + ".user"); //用户名
                String password = props.getProperty(poolName + ".password"); //密码
                String maxconn = props.getProperty(poolName + ".maxconn", "0"); //最大连接数
                int max; //定义一个整形变量
                try {
                    max = Integer.valueOf(maxconn).intValue(); //取得最大连接数的值
                }
                catch (NumberFormatException e) {
                    Debug.writeLog("错误的最大连接数限制: " + maxconn + " .连接池: " +
                                   poolName);
                    max = 0;
                }
                //创建连接池对象并把它保存在实例变量pools中
                DBConnectionPool pool = new DBConnectionPool(poolName, url, user, password, max);
                //散列表(Hashtable类 )pools实现连接池名字到连接池对象之间的映射,此处以连接池名字为键,连接池对象为值。
                pools.put(poolName, pool);
                Debug.writeLog("成功创建连接池" + poolName); //12、成功创建连接池Connection
            }
        }
    }

    /**
     * 将连接对象返回给由名字指定的连接池
     * @param name 在属性文件中定义的连接池名字
     * @param con 连接对象
     */
    public void freeConnection(String name, Connection con) {
        DBConnectionPool pool = (DBConnectionPool) pools.get(name);
        if (pool != null) {
            pool.freeConnection(con);
        }
    }

    /**
     * 获得一个可用的(空闲的)连接.如果没有可用连接,且已有连接数小于最大连接数
     * 限制,则创建并返回新连接
     * @param name 在属性文件中定义的连接池名字
     * @return Connection 可用连接或null
     */
    public Connection getConnection(String name) {
        DBConnectionPool pool = (DBConnectionPool) pools.get(name);
        if (pool != null) {
            Debug.writeLog(
                "DBConnectionManager getConnection(String) ! pool is not null !"); //20
            return pool.getConnection();
        }
        return null;
    }

    /**
     * 获得一个可用连接.若没有可用连接,且已有连接数小于最大连接数限制,
     * 则创建并返回新连接.否则,在指定的时间内等待其它线程释放连接.
     * @param name 连接池名字
     * @param time 以毫秒计的等待时间
     * @return Connection 可用连接或null
     */
    public Connection getConnection(String name, long time) {
        DBConnectionPool pool = (DBConnectionPool) pools.get(name);
        if (pool != null) {
            return pool.getConnection(time);
        }
        return null;
    }

    /**
     * 其引用就一直保存在静态变量instance中
     * 每次调用getInstance()都增加一个DBConnectionManager的客户程序计数。
     * 该计数代表引用DBConnectionManager唯一实例的客户程序总数,它将被用于控制连接池的关闭操作。
     * @return 返回唯一实例.如果是第一次调用此方法,则创建实例
     */
    public static synchronized DBConnectionManager getInstance() {
        if (instance == null) {
            instance = new DBConnectionManager();
        }
        clients++; //对客户端的访问计数
        return instance;
    }

    /**
     * 读取属性完成初始化
     */
    private void init() {
        //[配置文件路径(ISiteEnvironment.ConfigFile)]调用EnvironmentConfig的getProperties()方法
        Properties dbProps = EnvironmentConfig.getInstance().getProperties(
            ISiteEnvironment.ConfigFile);
        loadDrivers(dbProps); //装载驱动
        createPools(dbProps); //调用私有方法createPools()创建连接池对象
    }

    /**
     * 装载和注册所有JDBC驱动程序
     * 该方法先用StringTokenizer将drivers属性值分割为对应于驱动程序名称的字符串
     *
     * @param props 属性
     */
    private void loadDrivers(Properties props) {
        String driverClasses = props.getProperty("drivers");
        StringTokenizer st = new StringTokenizer(driverClasses);
        while (st.hasMoreElements()) {
            String driverClassName = st.nextToken().trim(); //取得驱动程序org.gjt.mm.mysql.Driver
            try {
                Driver driver = (Driver) Class.forName(driverClassName).
                    newInstance();
                DriverManager.registerDriver(driver);
                Debug.writeLog("Load Driver Success !"); //1、加载驱动成功
                drivers.addElement(driver);
                Debug.writeLog("成功注册JDBC驱动程序" + driverClassName); //2、加载JDBC驱动程序org.gjt.mm.mysql.Driver
            }
            catch (Exception e) {
                Debug.writeLog("无法注册JDBC驱动程序: " + driverClassName + ", 错误: " +  e);
            }
        }
    }

    /**
     * 客户程序在关闭时调用release()可以递减该计数。
     * 当最后一个客户程序调用release(),递减后的引用计数为0,就可以调用各个连接池的release()方法关闭所有连接了。
     * 关闭所有连接,撤销驱动程序的注册
     */
    public synchronized void release() { //等待直到最后一个客户程序调用
        if (--clients != 0) {
            return;
        }
        Enumeration allPools = pools.elements();
        while (allPools.hasMoreElements()) {
            DBConnectionPool pool = (DBConnectionPool) allPools.nextElement();
            pool.release();
        }
        Enumeration allDrivers = drivers.elements();
        while (allDrivers.hasMoreElements()) {
            Driver driver = (Driver) allDrivers.nextElement();
            try {
                DriverManager.deregisterDriver(driver);
                Debug.writeLog("撤销JDBC驱动程序 " + driver.getClass().getName() + "的注册");
            }
            catch (SQLException e) {
                Debug.writeLog("无法撤销下列JDBC驱动程序的注册: " + driver.getClass().getName());
                e.printStackTrace(System.out);
            }
        }
    }
}

⌨️ 快捷键说明

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