JDBC连接池

1. 引言 

  近年来,随着Internet/Intranet建网技术的飞速发展和在世界范围内的迅速普及,计算机 

  应用程序已从传统的桌面应用转到Web应用。基于B/S(Browser/Server)架构的3层开发模式逐渐取代C/S(Client/Server)架构的开发模式,成为开发企业级应用和电子商务普遍采用的技术。在Web应用开发的早期,主要使用的技术是CGI﹑ASP﹑PHP等。之后,Sun公司推出了基于Java语言的Servlet+Jsp+JavaBean技术。相比传统的开发技术,它具有跨平台﹑安全﹑有效﹑可移植等特性,这使其更便于使用和开发。 

  Java应用程序访问数据库的基本原理 

  在Java语言中,JDBC(Java DataBase Connection)是应用程序与数据库沟通的桥梁, 

  即Java语言通过JDBC技术访问数据库。JDBC是一种“开放”的方案,它为数据库应用开发人员﹑数据库前台工具开发人员提供了一种标准的应用程序设计接口,使开发人员可以用纯Java语言编写完整的数据库应用程序。JDBC提供两种API,分别是面向开发人员的API和面向底层的JDBC驱动程序API,底层主要通过直接的JDBC驱动和JDBC-ODBC桥驱动实现与数据库的连接。 

  一般来说,Java应用程序访问数据库的过程(如图1所示)是: 

  ①装载数据库驱动程序; 

  ②通过JDBC建立数据库连接; 

  ③访问数据库,执行SQL语句; 

  ④断开数据库连接。 

  Java数据库访问机制 
  JDBC作为一种数据库访问技术,具有简单易用的优点。但使用这种模式进行Web应用程序开发,存在很多问题:

  首先,每一次Web请求都要建立一次数据库连接。建立连接是一个费时的活动,每次都得花费0.05s~1s的时间,而且系统还要分配内存资源。这个时间对于一次或几次数据库操作,或许感觉不出系统有多大的开销。可是对于现在的Web应用,尤其是大型电子商务网站,同时有几百人甚至几千人在线是很正常的事。在这种情况下,频繁的进行数据库连接操作势必占用很多的系统资源,网站的响应速度必定下降,严重的甚至会造成服务器的崩溃。不是危言耸听,这就是制约某些电子商务网站发展的技术瓶颈问题。其次,对于每一次数据库连接,使用完后都得断开。否则,如果程序出现异常而未能关闭,将会导致数据库系统中的内存泄漏,最终将不得不重启数据库。还有,这种开发不能控制被创建的连接对象数,系统资源会被毫无顾及的分配出去,如连接过多,也可能导致内存泄漏,服务器崩溃。 

  数据库连接池(connection pool)的工作原理 
  1、基本概念及原理 
     由上面的分析可以看出,问题的根源就在于对数据库连接资源的低效管理。我们知道, 对于共享资源,有一个很著名的设计模式:资源池(Resource Pool)。该模式正是为了解决资源的频繁分配﹑释放所造成的问题。为解决上述问题,可以采用数据库连接池技术。数据库连接池的基本思想就是为数据库连接建立一个“缓冲池”。预先在缓冲池中放入一定数量的连接,当需要建立数据库连接时,只需从“缓冲池”中取出一个,使用完毕之后再放回去。我们可以通过设定连接池最大连接数来防止系统无尽的与数据库连接。更为重要的是我们可以通过连接池的管理机制监视数据库的连接的数量﹑使用情况,为系统开发﹑测试及性能调整提供依据。

  连接池的基本工作原理 
  2、服务器自带的连接池 
  JDBC的API中没有提供连接池的方法。一些大型的WEB应用服务器如BEA的WebLogic和IBM的WebSphere等提供了连接池的机制,但是必须有其第三方的专用类方法支持连接池的用法。 
  连接池关键问题分析 
  1、并发问题 
  为了使连接管理服务具有最大的通用性,必须考虑多线程环境,即并发问题。这个问题相对比较好解决,因为Java语言自身提供了对并发管理的支持,使用synchronized关键字即可确保线程是同步的。使用方法为直接在类方法前面加上synchronized关键字,如: 
public synchronized Connection getConnection() 
  2、多数据库服务器和多用户 
  对于大型的企业级应用,常常需要同时连接不同的数据库(如连接Oracle和Sybase)。如何连接不同的数据库呢?我们采用的策略是:设计一个符合单例模式的连接池管理类,在连接池管理类的唯一实例被创建时读取一个资源文件,其中资源文件中存放着多个数据库的url地址(<poolName.url>)﹑用户名(<poolName.user>)﹑密码(<poolName.password>)等信息。如 tx.url=192.168.1.123:5000/tx_it,tx.user=cyl,tx.password=123456。根据资源文件提供的信息,创建多个连接池类的实例,每一个实例都是一个特定数据库的连接池。连接池管理类实例为每个连接池实例取一个名字,通过不同的名字来管理不同的连接池。 
  对于同一个数据库有多个用户使用不同的名称和密码访问的情况,也可以通过资源文件处理,即在资源文件中设置多个具有相同url地址,但具有不同用户名和密码的数据库连接信息。 
  3、事务处理 
  我们知道,事务具有原子性,此时要求对数据库的操作符合“ALL-ALL-NOTHING”原则,即对于一组SQL语句要么全做,要么全不做。 
在Java语言中,Connection类本身提供了对事务的支持,可以通过设置Connection的AutoCommit属性为false,然后显式的调用 commit或rollback方法来实现。但要高效的进行Connection复用,就必须提供相应的事务支持机制。可采用每一个事务独占一个连接来实现,这种方法可以大大降低事务管理的复杂性。 
  4、连接池的分配与释放 
  连接池的分配与释放,对系统的性能有很大的影响。合理的分配与释放,可以提高连接的复用度,从而降低建立新连接的开销,同时还可以加快用户的访问速度。 
  对于连接的管理可使用空闲池。即把已经创建但尚未分配出去的连接按创建时间存放到一个空闲池中。每当用户请求一个连接时,系统首先检查空闲池内有没有空闲连接。如果有就把建立时间最长(通过容器的顺序存放实现)的那个连接分配给他(实际是先做连接是否有效的判断,如果可用就分配给用户,如不可用就把这个连接从空闲池删掉,重新检测空闲池是否还有连接);如果没有则检查当前所开连接池是否达到连接池所允许的最大连接数(maxConn),如果没有达到,就新建一个连接,如果已经达到,就等待一定的时间(timeout)。如果在等待的时间内有连接被释放出来就可以把这个连接分配给等待的用户,如果等待时间超过预定时间timeout,则返回空值(null)。系统对已经分配出去正在使用的连接只做计数,当使用完后再返还给空闲池。对于空闲连接的状态,可开辟专门的线程定时检测,这样会花费一定的系统开销,但可以保证较快的响应速度。也可采取不开辟专门线程,只是在分配前检测的方法。 
  5、连接池的配置与维护 
  连接池中到底应该放置多少连接,才能使系统的性能最佳?系统可采取设置最小连接数(minConn)和最大连接数(maxConn)来控制连接池中的连接。最小连接数是系统启动时连接池所创建的连接数。如果创建过多,则系统启动就慢,但创建后系统的响应速度会很快;如果创建过少,则系统启动的很快,响应起来却慢。这样,可以在开发时,设置较小的最小连接数,开发起来会快,而在系统实际使用时设置较大的,因为这样对访问客户来说速度会快些。最大连接数是连接池中允许连接的最大数目,具体设置多少,要看系统的访问量,可通过反复测试,找到最佳点。 
  如何确保连接池中的最小连接数呢?有动态和静态两种策略。动态即每隔一定时间就对连接池进行检测,如果发现连接数量小于最小连接数,则补充相应数量的新连接,以保证连接池的正常运转。静态是发现空闲连接不够时再去检查。 
连接池的实现 
  1、连接池模型 
  本文讨论的连接池包括一个连接池类(DBConnectionPool)和一个连接池管理类(DBConnetionPoolManager)和一个配置文件操作类(ParseDSConfig)。连接池类是对某一数据库所有连接的“缓冲池”,主要实现以下功能:①从连接池获取或创建可用连接;②使用完毕之后,把连接返还给连接池;③在系统关闭前,断开所有连接并释放连接占用的系统资源;④还能够处理无效连接(原来登记为可用的连接,由于某种原因不再可用,如超时,通讯问题),并能够限制连接池中的连接总数不低于某个预定值和不超过某个预定值。(5)当多数据库时,且数据库是动态增加的话,将会加到配置文件中。 
  连接池管理类是连接池类的外覆类(wrapper),符合单例模式,即系统中只能有一个连接池管理类的实例。其主要用于对多个连接池对象的管理,具有以下功能:① 装载并注册特定数据库的JDBC驱动程序;②根据属性文件给定的信息,创建连接池对象;③为方便管理多个连接池对象,为每一个连接池对象取一个名字,实现连接池名字与其实例之间的映射;④跟踪客户使用连接情况,以便需要是关闭连接释放资源。连接池管理类的引入主要是为了方便对多个连接池的使用和管理,如系统需要连接不同的数据库,或连接相同的数据库但由于安全性问题,需要不同的用户使用不同的名称和密码。 
         2、连接池实现(可以适用多数据库类型的应用以及一种数据库类型多个数据库且数据 库的数量可以动态增加的应用程序) 


         1),DBConnectionPool.java      数据库连接池类 
         2),DBConnectionManager.java     数据库管理类 
         3),DSConfigBean .java                     单个数据库连接信息Bean 
         4),ParseDSConfig.java                     操作多(这个'多'包括不同的数据库和同一种数据库有多个数据库)数据 配置文件xml 
         5),ds.config.xml                              数据库配置文件xml


   原代码如下: 

DBConnectionPool.java
  1 package com.tony.db;
  2 
  3 import java.sql.Connection;
  4 import java.sql.DriverManager;
  5 import java.sql.SQLException;
  6 import java.util.ArrayList;
  7 import java.util.Iterator;
  8 import java.util.Timer;
  9 
 10 /**
 11  * Created with IntelliJ IDEA.数据库连接池类
 12  * User: Tony.Wang
 13  * Date: 12-9-24
 14  * Time: 上午8:59
 15  * To change this template use File | Settings | File Templates.
 16  */
 17 public class DBConnectionPool {
 18     private Connection con = null;
 19     private int inUsed = 0;    //使用的连接数
 20     private ArrayList freeConnections = new ArrayList();//容器,空闲连接
 21     private int minConn;     //最小连接数
 22     private int maxConn;     //最大连接
 23     private String name;     //连接池名字
 24     private String password; //密码
 25     private String url;      //数据库连接地址
 26     private String driver;   //驱动
 27     private String user;     //用户名
 28     public Timer timer;      //定时
 29 
 30     /**
 31      *
 32      */
 33     public DBConnectionPool() {
 34         // TODO Auto-generated constructor stub
 35     }
 36 
 37     /**
 38      * 创建连接池
 39      *
 40      * @param driver
 41      * @param name
 42      * @param URL
 43      * @param user
 44      * @param password
 45      * @param maxConn
 46      */
 47     public DBConnectionPool(String name, String driver, String URL, String user, String password, int maxConn) {
 48         this.name = name;
 49         this.driver = driver;
 50         this.url = URL;
 51         this.user = user;
 52         this.password = password;
 53         this.maxConn = maxConn;
 54     }
 55 
 56     /**
 57      * 用完,释放连接
 58      *
 59      * @param con
 60      */
 61     public synchronized void freeConnection(Connection con) {
 62         this.freeConnections.add(con);//添加到空闲连接的末尾
 63         this.inUsed--;
 64     }
 65 
 66     /**
 67      * timeout  根据timeout得到连接
 68      *
 69      * @param timeout
 70      * @return
 71      */
 72     public synchronized Connection getConnection(long timeout) {
 73         Connection con = null;
 74         if (this.freeConnections.size() > 0) {
 75             con = (Connection) this.freeConnections.get(0);
 76             if (con == null) con = getConnection(timeout); //继续获得连接
 77         } else {
 78             con = newConnection(); //新建连接
 79         }
 80         if (this.maxConn == 0 || this.maxConn < this.inUsed) {
 81             con = null;//达到最大连接数,暂时不能获得连接了。
 82         }
 83         if (con != null) {
 84             this.inUsed++;
 85         }
 86         return con;
 87     }
 88 
 89     /**
 90      * 从连接池里得到连接
 91      *
 92      * @return
 93      */
 94     public synchronized Connection getConnection() {
 95         Connection con = null;
 96         if (this.freeConnections.size() > 0) {
 97             con = (Connection) this.freeConnections.get(0);
 98             this.freeConnections.remove(0);//如果连接分配出去了,就从空闲连接里删除
 99             if (con == null) con = getConnection(); //继续获得连接
100         } else {
101             con = newConnection(); //新建连接
102         }
103         if (this.maxConn == 0 || this.maxConn < this.inUsed) {
104             con = null;//等待 超过最大连接时
105         }
106         if (con != null) {
107             this.inUsed++;
108             System.out.println("得到 " + this.name + " 的连接,现有" + inUsed + "个连接在使用!");
109         }
110         return con;
111     }
112 
113     /**
114      * 释放全部连接
115      */
116     public synchronized void release() {
117         Iterator allConns = this.freeConnections.iterator();
118         while (allConns.hasNext()) {
119             Connection con = (Connection) allConns.next();
120             try {
121                 con.close();
122             } catch (SQLException e) {
123                 e.printStackTrace();
124             }
125 
126         }
127         this.freeConnections.clear();
128 
129     }
130 
131     /**
132      * 创建新连接
133      *
134      * @return
135      */
136     private Connection newConnection() {
137         try {
138             Class.forName(driver);
139             con = DriverManager.getConnection(url, user, password);
140         } catch (ClassNotFoundException e) {
141             // TODO Auto-generated catch block
142             e.printStackTrace();
143             System.out.println("sorry can't find db driver!");
144         } catch (SQLException e1) {
145             // TODO Auto-generated catch block
146             e1.printStackTrace();
147             System.out.println("sorry can't create Connection!");
148         }
149         return con;
150 
151     }
152 
153     /**
154      * 定时处理函数
155      */
156     public synchronized void TimerEvent() {
157         //暂时还没有实现以后会加上的
158     }
159 
160     /**
161      * @param args
162      */
163     public static void main(String[] args) {
164         // TODO Auto-generated method stub
165     }
166 
167     /**
168      * @return the driver
169      */
170     public String getDriver() {
171         return driver;
172     }
173 
174     /**
175      * @param driver the driver to set
176      */
177     public void setDriver(String driver) {
178         this.driver = driver;
179     }
180 
181     /**
182      * @return the maxConn
183      */
184     public int getMaxConn() {
185         return maxConn;
186     }
187 
188     /**
189      * @param maxConn the maxConn to set
190      */
191     public void setMaxConn(int maxConn) {
192         this.maxConn = maxConn;
193     }
194 
195     /**
196      * @return the minConn
197      */
198     public int getMinConn() {
199         return minConn;
200     }
201 
202     /**
203      * @param minConn the minConn to set
204      */
205     public void setMinConn(int minConn) {
206         this.minConn = minConn;
207     }
208 
209     /**
210      * @return the name
211      */
212     public String getName() {
213         return name;
214     }
215 
216     /**
217      * @param name the name to set
218      */
219     public void setName(String name) {
220         this.name = name;
221     }
222 
223     /**
224      * @return the password
225      */
226     public String getPassword() {
227         return password;
228     }
229 
230     /**
231      * @param password the password to set
232      */
233     public void setPassword(String password) {
234         this.password = password;
235     }
236 
237     /**
238      * @return the url
239      */
240     public String getUrl() {
241         return url;
242     }
243 
244     /**
245      * @param url the url to set
246      */
247     public void setUrl(String url) {
248         this.url = url;
249     }
250 
251     /**
252      * @return the user
253      */
254     public String getUser() {
255         return user;
256     }
257 
258     /**
259      * @param user the user to set
260      */
261     public void setUser(String user) {
262         this.user = user;
263     }
264 } 
DBConnectionManager.java
  1 package com.tony.db;
  2 
  3 import java.sql.Connection;
  4 import java.util.Enumeration;
  5 import java.util.Hashtable;
  6 import java.util.Iterator;
  7 import java.util.Vector;
  8 
  9 /**
 10  * Created with IntelliJ IDEA.数据库连接池管理类
 11  * User: Tony.Wang
 12  * Date: 12-9-24
 13  * Time: 上午8:59
 14  * To change this template use File | Settings | File Templates.
 15  */
 16 public class DBConnectionManager {
 17     static private DBConnectionManager instance;//唯一数据库连接池管理实例类
 18     static private int clients;                 //客户连接数
 19     private Vector drivers = new Vector();//驱动信息
 20     private Hashtable pools = new Hashtable();//连接池
 21 
 22     /**
 23      * 实例化管理类
 24      */
 25     public DBConnectionManager() {
 26         // TODO Auto-generated constructor stub
 27         this.init();
 28     }
 29 
 30     /**
 31      * 得到唯一实例管理类
 32      *
 33      * @return
 34      */
 35     static synchronized public DBConnectionManager getInstance() {
 36         if (instance == null) {
 37             instance = new DBConnectionManager();
 38         }
 39         return instance;
 40 
 41     }
 42 
 43     /**
 44      * 释放连接
 45      *
 46      * @param name
 47      * @param con
 48      */
 49     public void freeConnection(String name, Connection con) {
 50         DBConnectionPool pool = (DBConnectionPool) pools.get(name);//根据关键名字得到连接池
 51         if (pool != null)
 52             pool.freeConnection(con);//释放连接
 53     }
 54 
 55     public void freeConnection() {
 56 
 57     }
 58 
 59     /**
 60      * 得到一个连接根据连接池的名字name
 61      *
 62      * @param name
 63      * @return
 64      */
 65     public Connection getConnection(String name) {
 66         DBConnectionPool pool = null;
 67         Connection con = null;
 68         pool = (DBConnectionPool) pools.get(name);//从名字中获取连接池
 69         con = pool.getConnection();//从选定的连接池中获得连接
 70         if (con != null)
 71             System.out.println("得到连接。。。");
 72         return con;
 73     }
 74 
 75     /**
 76      * 得到一个连接,根据连接池的名字和等待时间
 77      *
 78      * @param name
 79      * @param timeout
 80      * @return
 81      */
 82     public Connection getConnection(String name, long timeout) {
 83         DBConnectionPool pool = null;
 84         Connection con = null;
 85         pool = (DBConnectionPool) pools.get(name);//从名字中获取连接池
 86         con = pool.getConnection(timeout);//从选定的连接池中获得连接
 87         System.out.println("得到连接。。。");
 88         return con;
 89     }
 90 
 91     /**
 92      * 释放所有连接
 93      */
 94     public synchronized void release() {
 95         Enumeration allpools = pools.elements();
 96         while (allpools.hasMoreElements()) {
 97             DBConnectionPool pool = (DBConnectionPool) allpools.nextElement();
 98             if (pool != null) pool.release();
 99         }
100         pools.clear();
101     }
102 
103     /**
104      * 创建连接池
105      *
106      * @param dsb
107      */
108     private void createPools(DSConfigBean dsb) {
109         DBConnectionPool dbpool = new DBConnectionPool();
110         dbpool.setName(dsb.getName());
111         dbpool.setDriver(dsb.getDriver());
112         dbpool.setUrl(dsb.getUrl());
113         dbpool.setUser(dsb.getUsername());
114         dbpool.setPassword(dsb.getPassword());
115         dbpool.setMaxConn(dsb.getMaxconn());
116         System.out.println("ioio:" + dsb.getMaxconn());
117         pools.put(dsb.getName(), dbpool);
118     }
119 
120     /**
121      * 初始化连接池的参数
122      */
123     private void init() {
124         //加载驱动程序
125         this.loadDrivers();
126         //创建连接池
127         Iterator alldriver = drivers.iterator();
128         while (alldriver.hasNext()) {
129             this.createPools((DSConfigBean) alldriver.next());
130             System.out.println("创建连接池。。。");
131 
132         }
133         System.out.println("创建连接池完毕。。。");
134     }
135 
136     /**
137      * 加载驱动程序
138      *
139      */
140     private void loadDrivers() {
141         ParseDSConfig pd = new ParseDSConfig();
142 //读取数据库配置文件
143         drivers = pd.readConfigInfo("ds.config.xml");
144         System.out.println("加载驱动程序。。。");
145     }
146 
147     /**
148      * @param args
149      */
150     public static void main(String[] args) {
151         // TODO Auto-generated method stub
152     }
153 }
ParseDSConfig.java
  1 package com.tony.db;
  2 
  3 import org.jdom.Document;
  4 import org.jdom.Element;
  5 import org.jdom.JDOMException;
  6 import org.jdom.input.SAXBuilder;
  7 import org.jdom.output.Format;
  8 import org.jdom.output.XMLOutputter;
  9 
 10 import java.io.FileInputStream;
 11 import java.io.FileNotFoundException;
 12 import java.io.FileOutputStream;
 13 import java.io.IOException;
 14 import java.util.Iterator;
 15 import java.util.List;
 16 import java.util.Vector;
 17 
 18 /**
 19  * Created with IntelliJ IDEA.操作配置文件类 读、写、修改、删除等操作
 20  * User: Tony.Wang
 21  * Date: 12-9-24
 22  * Time: 上午9:01
 23  * To change this template use File | Settings | File Templates.
 24  */
 25 public class ParseDSConfig {
 26     /**
 27      * 构造函数
 28      */
 29     public ParseDSConfig() {
 30         // TODO Auto-generated constructor stub
 31     }
 32 
 33     /**
 34      * 读取xml配置文件
 35      *
 36      * @param path
 37      * @return
 38      */
 39     public Vector readConfigInfo(String path) {
 40         String rpath = this.getClass().getResource("").getPath().substring(1) + path;
 41         Vector dsConfig = null;
 42         FileInputStream fi = null;
 43         try {
 44             fi = new FileInputStream(rpath);//读取路径文件
 45             dsConfig = new Vector();
 46             SAXBuilder sb = new SAXBuilder();
 47             Document doc = sb.build(fi);
 48             Element root = doc.getRootElement();
 49             List pools = root.getChildren();
 50             Element pool = null;
 51             Iterator allPool = pools.iterator();
 52             while (allPool.hasNext()) {
 53                 pool = (Element) allPool.next();
 54                 DSConfigBean dscBean = new DSConfigBean();
 55                 dscBean.setType(pool.getChild("type").getText());
 56                 dscBean.setName(pool.getChild("name").getText());
 57                 System.out.println(dscBean.getName());
 58                 dscBean.setDriver(pool.getChild("driver").getText());
 59                 dscBean.setUrl(pool.getChild("url").getText());
 60                 dscBean.setUsername(pool.getChild("username").getText());
 61                 dscBean.setPassword(pool.getChild("password").getText());
 62                 dscBean.setMaxconn(Integer.parseInt(pool.getChild("maxconn").getText()));
 63                 dsConfig.add(dscBean);
 64             }
 65 
 66         } catch (FileNotFoundException e) {
 67             // TODO Auto-generated catch block
 68             e.printStackTrace();
 69         } catch (JDOMException e) {
 70             // TODO Auto-generated catch block
 71             e.printStackTrace();
 72         } catch (IOException e) {
 73             // TODO Auto-generated catch block
 74             e.printStackTrace();
 75         } finally {
 76             try {
 77                 fi.close();
 78             } catch (IOException e) {
 79                 // TODO Auto-generated catch block
 80                 e.printStackTrace();
 81             }
 82         }
 83 
 84         return dsConfig;
 85     }
 86 
 87     /**
 88      * 修改配置文件 没时间写 过段时间再贴上去 其实一样的
 89      */
 90     public void modifyConfigInfo(String path, DSConfigBean dsb) throws Exception {
 91         String rpath = this.getClass().getResource("").getPath().substring(1) + path;
 92         FileInputStream fi = null; //读出
 93         FileOutputStream fo = null; //写入
 94 
 95     }
 96 
 97     /**
 98      * 增加配置文件
 99      */
100     public void addConfigInfo(String path, DSConfigBean dsb) {
101         String rpath = this.getClass().getResource("").getPath().substring(1) + path;
102         FileInputStream fi = null;
103         FileOutputStream fo = null;
104         try {
105             fi = new FileInputStream(rpath);//读取xml流
106 
107             SAXBuilder sb = new SAXBuilder();
108 
109             Document doc = sb.build(fi); //得到xml
110             Element root = doc.getRootElement();
111             List pools = root.getChildren();//得到xml子树
112 
113             Element newpool = new Element("pool"); //创建新连接池
114 
115             Element pooltype = new Element("type"); //设置连接池类型
116             pooltype.setText(dsb.getType());
117             newpool.addContent(pooltype);
118 
119             Element poolname = new Element("name");//设置连接池名字
120             poolname.setText(dsb.getName());
121             newpool.addContent(poolname);
122 
123             Element pooldriver = new Element("driver"); //设置连接池驱动
124             pooldriver.addContent(dsb.getDriver());
125             newpool.addContent(pooldriver);
126 
127             Element poolurl = new Element("url");//设置连接池url
128             poolurl.setText(dsb.getUrl());
129             newpool.addContent(poolurl);
130 
131             Element poolusername = new Element("username");//设置连接池用户名
132             poolusername.setText(dsb.getUsername());
133             newpool.addContent(poolusername);
134 
135             Element poolpassword = new Element("password");//设置连接池密码
136             poolpassword.setText(dsb.getPassword());
137             newpool.addContent(poolpassword);
138 
139             Element poolmaxconn = new Element("maxconn");//设置连接池最大连接
140             poolmaxconn.setText(String.valueOf(dsb.getMaxconn()));
141             newpool.addContent(poolmaxconn);
142             pools.add(newpool);//将child添加到root
143             Format format = Format.getPrettyFormat();
144             format.setIndent("");
145             format.setEncoding("utf-8");
146             XMLOutputter outp = new XMLOutputter(format);
147             fo = new FileOutputStream(rpath);
148             outp.output(doc, fo);
149         } catch (FileNotFoundException e) {
150             // TODO Auto-generated catch block
151             e.printStackTrace();
152         } catch (JDOMException e) {
153             // TODO Auto-generated catch block
154             e.printStackTrace();
155         } catch (IOException e) {
156             // TODO Auto-generated catch block
157             e.printStackTrace();
158         } finally {
159 
160         }
161     }
162 
163     /**
164      * 删除配置文件
165      */
166     public void delConfigInfo(String path, String name) {
167         String rpath = this.getClass().getResource("").getPath().substring(1) + path;
168         FileInputStream fi = null;
169         FileOutputStream fo = null;
170         try {
171             fi = new FileInputStream(rpath);//读取路径文件
172             SAXBuilder sb = new SAXBuilder();
173             Document doc = sb.build(fi);
174             Element root = doc.getRootElement();
175             List pools = root.getChildren();
176             Element pool = null;
177             Iterator allPool = pools.iterator();
178             while (allPool.hasNext()) {
179                 pool = (Element) allPool.next();
180                 if (pool.getChild("name").getText().equals(name)) {
181                     pools.remove(pool);
182                     break;
183                 }
184             }
185             Format format = Format.getPrettyFormat();
186             format.setIndent("");
187             format.setEncoding("utf-8");
188             XMLOutputter outp = new XMLOutputter(format);
189             fo = new FileOutputStream(rpath);
190             outp.output(doc, fo);
191 
192         } catch (FileNotFoundException e) {
193             // TODO Auto-generated catch block
194             e.printStackTrace();
195         } catch (JDOMException e) {
196             // TODO Auto-generated catch block
197             e.printStackTrace();
198         } catch (IOException e) {
199             // TODO Auto-generated catch block
200             e.printStackTrace();
201         } finally {
202             try {
203                 fi.close();
204             } catch (IOException e) {
205                 // TODO Auto-generated catch block
206                 e.printStackTrace();
207             }
208         }
209     }
210 
211     /**
212      * @param args
213      * @throws Exception
214      */
215     public static void main(String[] args) throws Exception {
216         // TODO Auto-generated method stub
217         ParseDSConfig pd = new ParseDSConfig();
218         String path = "ds.config.xml";
219         pd.readConfigInfo(path);
220         //pd.delConfigInfo(path, "tj012006");
221         DSConfigBean dsb = new DSConfigBean();
222         dsb.setType("oracle");
223         dsb.setName("yyy004");
224         dsb.setDriver("org.oracle.jdbc");
225         dsb.setUrl("jdbc:oracle://localhost");
226         dsb.setUsername("sa");
227         dsb.setPassword("");
228         dsb.setMaxconn(1000);
229         pd.addConfigInfo(path, dsb);
230         pd.delConfigInfo(path, "yyy001");
231     }
232 }
ds.config.xml
 1 <ds-config>
 2     <pool>
 3         <type>mysql</type>
 4         <name>user</name>
 5         <driver>com.mysql.jdbc.driver</driver>
 6         <url>jdbc:mysql://localhost:3306/user</url>
 7         <username>sa</username>
 8         <password>123456</password>
 9         <maxconn>100</maxconn>
10     </pool>
11     <pool>
12         <type>mysql</type>
13         <name>user2</name>
14         <driver>com.mysql.jdbc.driver</driver>
15         <url>jdbc:mysql://localhost:3306/user2</url>
16         <username>sa</username>
17         <password>1234</password>
18         <maxconn>10</maxconn>
19     </pool>
20     <pool>
21         <type>sql2000</type>
22         <name>books</name>
23         <driver>com.microsoft.sqlserver.driver</driver>
24         <url>jdbc:sqlserver://localhost:1433/books:databasename=books</url>
25         <username>sa</username>
26         <password></password>
27         <maxconn>100</maxconn>
28     </pool>
29 </ds-config>

3. 连接池的使用 

  1. Connection 的获得与释放

    

Test.java
 1 package com.tony.db;
 2 
 3 import java.sql.Connection;
 4 
 5 /**
 6  * Created with IntelliJ IDEA.
 7  * User: Tony.Wang
 8  * Date: 12-9-24
 9  * Time: 上午9:34
10  * To change this template use File | Settings | File Templates.
11  */
12 public class Test {
13 
14     public static void main(String[] args) {
15         DBConnectionManager connectionManager = DBConnectionManager.getInstance();
16         String name = "mysql";//从上下文得到你要访问的数据库的名字
17 
18         Connection connection = connectionManager.getConnection(name);
19         //使用
20 
21         //使用结束
22         connectionManager.freeConnection(name, connection);//释放,但并未断开连接
23     }
24 
25 }

  2. 数据库连接的动态增加和连接池的动态增加

    1.调用XML操作增加类

    2.重新实例化连接池管理类

原文地址:https://www.cnblogs.com/tonycody/p/2699532.html