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

📄 使用java中的动态代理实现数据库连接池.htm

📁 使用JAVA中的动态代理实现数据库连接池
💻 HTM
📖 第 1 页 / 共 3 页
字号:
                        ConnectionFactory<BR>{<BR>&nbsp;//该哈希表用来保存数据源名和连接池对象的关系表<BR>&nbsp;static 
                        Hashtable connectionPools = 
                        null;<BR>&nbsp;static{<BR>&nbsp;&nbsp;connectionPools = 
                        new Hashtable(2,0.75F);<BR>&nbsp;} 
                        <BR>&nbsp;/**<BR>&nbsp; * 
                        从连接池工厂中获取指定名称对应的连接池对象<BR>&nbsp; * @param 
                        dataSource&nbsp;连接池对象对应的名称<BR>&nbsp; * @return 
                        DataSource&nbsp;返回名称对应的连接池对象<BR>&nbsp; * @throws 
                        NameNotFoundException&nbsp;无法找到指定的连接池<BR>&nbsp; 
                        */<BR>&nbsp;public static DataSource lookup(String 
                        dataSource) <BR>&nbsp;&nbsp;throws 
                        NameNotFoundException<BR>&nbsp;{<BR>&nbsp;&nbsp;Object 
                        ds = null;<BR>&nbsp;&nbsp;ds = 
                        connectionPools.get(dataSource);<BR>&nbsp;&nbsp;if(ds == 
                        null || !(ds instanceof 
                        DataSource))<BR>&nbsp;&nbsp;&nbsp;throw new 
                        NameNotFoundException(dataSource);<BR>&nbsp;&nbsp;return 
                        (DataSource)ds;<BR>&nbsp;}<BR><BR>&nbsp;/**<BR>&nbsp; * 
                        将指定的名字和数据库连接配置绑定在一起并初始化数据库连接池<BR>&nbsp; * @param 
                        name&nbsp;&nbsp;对应连接池的名称<BR>&nbsp; * @param 
                        param&nbsp;连接池的配置参数,具体请见类ConnectionParam<BR>&nbsp; * 
                        @return DataSource&nbsp;如果绑定成功后返回连接池对象<BR>&nbsp; * 
                        @throws 
                        NameAlreadyBoundException&nbsp;一定名字name已经绑定则抛出该异常<BR>&nbsp; 
                        * @throws 
                        ClassNotFoundException&nbsp;&nbsp;无法找到连接池的配置中的驱动程序类<BR>&nbsp; 
                        * @throws 
                        IllegalAccessException&nbsp;&nbsp;连接池配置中的驱动程序类有误<BR>&nbsp; 
                        * @throws 
                        InstantiationException&nbsp;&nbsp;无法实例化驱动程序类<BR>&nbsp; * 
                        @throws 
                        SQLException&nbsp;&nbsp;&nbsp;&nbsp;无法正常连接指定的数据库<BR>&nbsp; 
                        */<BR>&nbsp;public static DataSource bind(String name, 
                        ConnectionParam param)<BR>&nbsp;&nbsp;throws 
                        NameAlreadyBoundException,ClassNotFoundException,<BR>&nbsp;&nbsp;&nbsp;&nbsp;IllegalAccessException,InstantiationException,SQLException<BR>&nbsp;{<BR>&nbsp;&nbsp;DataSourceImpl 
                        source = 
                        null;<BR>&nbsp;&nbsp;try{<BR>&nbsp;&nbsp;&nbsp;lookup(name);<BR>&nbsp;&nbsp;&nbsp;throw 
                        new 
                        NameAlreadyBoundException(name);<BR>&nbsp;&nbsp;}catch(NameNotFoundException 
                        e){<BR>&nbsp;&nbsp;&nbsp;source = new 
                        DataSourceImpl(param);<BR>&nbsp;&nbsp;&nbsp;source.initConnection();<BR>&nbsp;&nbsp;&nbsp;connectionPools.put(name, 
                        source);<BR>&nbsp;&nbsp;}<BR>&nbsp;&nbsp;return 
                        source;<BR>&nbsp;}<BR>&nbsp;/**<BR>&nbsp; * 
                        重新绑定数据库连接池<BR>&nbsp; * @param 
                        name&nbsp;&nbsp;对应连接池的名称<BR>&nbsp; * @param 
                        param&nbsp;连接池的配置参数,具体请见类ConnectionParam<BR>&nbsp; * 
                        @return DataSource&nbsp;如果绑定成功后返回连接池对象<BR>&nbsp; * 
                        @throws 
                        NameAlreadyBoundException&nbsp;一定名字name已经绑定则抛出该异常<BR>&nbsp; 
                        * @throws 
                        ClassNotFoundException&nbsp;&nbsp;无法找到连接池的配置中的驱动程序类<BR>&nbsp; 
                        * @throws 
                        IllegalAccessException&nbsp;&nbsp;连接池配置中的驱动程序类有误<BR>&nbsp; 
                        * @throws 
                        InstantiationException&nbsp;&nbsp;无法实例化驱动程序类<BR>&nbsp; * 
                        @throws 
                        SQLException&nbsp;&nbsp;&nbsp;&nbsp;无法正常连接指定的数据库<BR>&nbsp; 
                        */<BR>&nbsp;public static DataSource rebind(String name, 
                        ConnectionParam param)<BR>&nbsp;&nbsp;throws 
                        NameAlreadyBoundException,ClassNotFoundException,<BR>&nbsp;&nbsp;&nbsp;&nbsp;IllegalAccessException,InstantiationException,SQLException<BR>&nbsp;{<BR>&nbsp;&nbsp;try{<BR>&nbsp;&nbsp;&nbsp;unbind(name);<BR>&nbsp;&nbsp;}catch(Exception 
                        e){}<BR>&nbsp;&nbsp;return bind(name, 
                        param);<BR>&nbsp;}<BR>&nbsp;/**<BR>&nbsp; * 
                        删除一个数据库连接池对象<BR>&nbsp; * @param name<BR>&nbsp; * @throws 
                        NameNotFoundException<BR>&nbsp; */<BR>&nbsp;public 
                        static void unbind(String name) throws 
                        NameNotFoundException<BR>&nbsp;{<BR>&nbsp;&nbsp;DataSource 
                        dataSource = lookup(name);<BR>&nbsp;&nbsp;if(dataSource 
                        instanceof 
                        DataSourceImpl){<BR>&nbsp;&nbsp;&nbsp;DataSourceImpl dsi 
                        = 
                        (DataSourceImpl)dataSource;<BR>&nbsp;&nbsp;&nbsp;try{<BR>&nbsp;&nbsp;&nbsp;&nbsp;dsi.stop();<BR>&nbsp;&nbsp;&nbsp;&nbsp;dsi.close();<BR>&nbsp;&nbsp;&nbsp;}catch(Exception 
                        e){<BR>&nbsp;&nbsp;&nbsp;}finally{<BR>&nbsp;&nbsp;&nbsp;&nbsp;dsi 
                        = 
                        null;<BR>&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;}<BR>&nbsp;&nbsp;connectionPools.remove(name);<BR>&nbsp;}<BR>&nbsp;<BR>}</P>
                        <P>  ConnectionFactory主要提供了用户将将连接池绑定到一个具体的名称上以及取消绑定的操作。使用者只需要关心这两个类即可使用数据库连接池的功能。下面我们给出一段如何使用连接池的代码:</P>
                        <P style="BACKGROUND: #eeeeee">&nbsp;String name = 
                        "pool";<BR>&nbsp;String driver = " 
                        sun.jdbc.odbc.JdbcOdbcDriver ";<BR>&nbsp;String url = 
                        "jdbc:odbc:datasource";<BR>&nbsp;ConnectionParam param = 
                        new 
                        ConnectionParam(driver,url,null,null);<BR>&nbsp;param.setMinConnection(1);<BR>&nbsp;param.setMaxConnection(5);<BR>&nbsp;param.setTimeoutValue(20000);<BR>&nbsp;ConnectionFactory.bind(name, 
                        param);<BR>&nbsp;System.out.println("bind datasource 
                        ok.");<BR>&nbsp;//以上代码是用来登记一个连接池对象,该操作可以在程序初始化只做一次即可<BR>&nbsp;//以下开始就是使用者真正需要写的代码<BR>&nbsp;DataSource 
                        ds = 
                        ConnectionFactory.lookup(name);<BR>&nbsp;try{<BR>&nbsp;&nbsp;for(int 
                        i=0;i&lt;10;i++){<BR>&nbsp;&nbsp;&nbsp;Connection conn = 
                        ds.getConnection();<BR>&nbsp;&nbsp;&nbsp;try{<BR>&nbsp;&nbsp;&nbsp;&nbsp;testSQL(conn, 
                        sql);<BR>&nbsp;&nbsp;&nbsp;}finally{<BR>&nbsp;&nbsp;&nbsp;&nbsp;try{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;conn.close();<BR>&nbsp;&nbsp;&nbsp;&nbsp;}catch(Exception 
                        e){}<BR>&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;}<BR>&nbsp;}catch(Exception 
                        e){<BR>&nbsp;&nbsp;e.printStackTrace();<BR>&nbsp;}finally{<BR>&nbsp;&nbsp;ConnectionFactory.unbind(name);<BR>&nbsp;&nbsp;System.out.println("unbind 
                        datasource 
                        ok.");<BR>&nbsp;&nbsp;System.exit(0);<BR>&nbsp;}</P>
                        <P>  从使用者的示例代码就可以看出,我们已经解决了常规连接池产生的两个问题。但是我们最最关心的是如何解决接管close方法的办法。接管工作主要在ConnectionFactory中的两句代码:</P>
                        <P style="BACKGROUND: #eeeeee">source = new 
                        DataSourceImpl(param);<BR>source.initConnection();</P>
                        <P>  DataSourceImpl是一个实现了接口javax.sql.DataSource的类,该类维护着一个连接池的对象。由于该类是一个受保护的类,因此它暴露给使用者的方法只有接口DataSource中定义的方法,其他的所有方法对使用者来说都是不可视的。我们先来关心用户可访问的一个方法getConnection</P>
                        <P style="BACKGROUND: #eeeeee">/**<BR>&nbsp;* @see 
                        javax.sql.DataSource#getConnection(String,String)<BR>&nbsp;*/<BR>&nbsp;public 
                        Connection getConnection(String user, String password) 
                        throws SQLException 
                        <BR>&nbsp;{<BR>&nbsp;&nbsp;//首先从连接池中找出空闲的对象<BR>&nbsp;&nbsp;Connection 
                        conn = getFreeConnection(0);<BR>&nbsp;&nbsp;if(conn == 
                        null){<BR>&nbsp;&nbsp;&nbsp;//判断是否超过最大连接数,如果超过最大连接数<BR>&nbsp;&nbsp;&nbsp;//则等待一定时间查看是否有空闲连接,否则抛出异常告诉用户无可用连接<BR>&nbsp;&nbsp;&nbsp;if(getConnectionCount() 
                        &gt;= 
                        connParam.getMaxConnection())<BR>&nbsp;&nbsp;&nbsp;&nbsp;conn 
                        = 
                        getFreeConnection(connParam.getWaitTime());<BR>&nbsp;&nbsp;&nbsp;else{//没有超过连接数,重新获取一个数据库的连接<BR>&nbsp;&nbsp;&nbsp;&nbsp;connParam.setUser(user);<BR>&nbsp;&nbsp;&nbsp;&nbsp;connParam.setPassword(password);<BR>&nbsp;&nbsp;&nbsp;&nbsp;Connection 
                        conn2 = DriverManager.getConnection(connParam.getUrl(), 
                        <BR>&nbsp;&nbsp;&nbsp;&nbsp;user, 
                        password);<BR>&nbsp;&nbsp;&nbsp;&nbsp;//代理将要返回的连接对象<BR>&nbsp;&nbsp;&nbsp;&nbsp;_Connection 
                        _conn = new 
                        _Connection(conn2,true);<BR>&nbsp;&nbsp;&nbsp;&nbsp;synchronized(conns){<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;conns.add(_conn);<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;conn 
                        = 
                        _conn.getConnection();<BR>&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;}<BR>&nbsp;&nbsp;return 

⌨️ 快捷键说明

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