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
原代码如下:
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 }
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 }
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 }
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 的获得与释放
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.重新实例化连接池管理类