日期:2014-05-16 浏览次数:20596 次
以前写一些作业性质的网站,在对数据库操作时,都会写一个DBConnection类,用来获取数据库的连接,操作完数据之后,马上释放该连接。这是最简单的方法,但性能上是有很大问题的。比如我曾经用单线程循环1000次数据操作,就会出现异常。这时,使用连接池效果会好不少。下面的代码是在别人基础上稍加修改而来的。
以下是一个数据库连接池,启动时先从属性文件中读出一些参数,并启动最小连接数。有外来请求,就从连接池中移走一个对象。当前连接池大小为0时,参考最大连接数,新建若干个链接。当连接数超出最大限制时,则不再新建连接,这时如果有新的连接请求,而连接池目前又没有空闲的连接的话,那就很抱歉,只能返回空了。(返回空必然会引发异常,这不是我们所希望看到的。谁如果有好的解决方案,望告知)。
ConnectionPool.java
import java.io.FileInputStream; import java.sql.Connection; import java.sql.SQLException; import java.util.Properties; import java.util.Vector; public class ConnectionPool { private Vector<Connection> pool; private String url; private String username; private String password; private String driverClassName; /** * 连接池的大小,也就是连接池中有多少个数据库连接。 */ private int poolSize; private int poolSizeMax; private static ConnectionPool instance = new ConnectionPool(); private ConnectionManager connectionManager; /** * 私有的构造方法,禁止外部创建本类的对象,要想获得本类的对象,通过<code>getIstance</code>方法。 * 使用了设计模式中的单子模式。 */ private ConnectionPool() { init(); } /** * 连接池初始化方法,读取属性文件的内容 建立连接池中的初始连接 */ private void init() { pool = new Vector<Connection>(); readConfig(); addConnection(poolSize); connectionManager = new ConnectionManager(pool); connectionManager.start(); } /** * 返回连接到连接池中 */ public synchronized void release(Connection conn) { pool.add(conn); } /** * 关闭连接池中的所有数据库连接 */ public synchronized void closePool() { for (int i = 0; i < pool.size(); i++) { try { ((Connection) pool.get(i)).close(); } catch (SQLException e) { e.printStackTrace(); } pool.remove(i); } } /** * 返回当前连接池的一个对象 */ public static ConnectionPool getInstance() { return instance; } /** * 返回连接池中的一个数据库连接 */ public synchronized Connection getConnection() { Connection conn; if (pool.size() <= 0) { if(poolSize<=(poolSizeMax>>2)) { addConnection(poolSize); poolSize<<=2; } else if(poolSize<poolSizeMax){ addConnection(poolSize); poolSize=poolSizeMax; } } conn = pool.remove(0);//pool.get(0),pool的size并不会减1 return conn; } /** * 在连接池中创建初始设置的的数据库连接 */ private void addConnection(int size) { Connection conn = null; for (int i = 0; i < size; i++) { try { Class.forName(driverClassName); conn = java.sql.DriverManager.getConnection(url, username, password); pool.add(conn); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } } } /** * 读取设置连接池的属性文件 */ private void readConfig() { try { String path = System.getProperty("user.dir") + "\\dbpool.properties"; FileInputStream is = new FileInputStream(path); Properties props = new Properties(); props.load(is); this.driverClassName = props.getProperty("driverClassName"); this.username = props.getProperty("username"); this.password = props.getProperty("password"); this.url = props.getProperty("url"); this.poolSize = Integer.parseInt(props.getProperty("poolSizeMin")); this.poolSizeMax = Integer.parseInt(props.getProperty("poolSizeMax")); } catch (Exception e) { e.printStackTrace(); System.err.println("读取属性文件出错. "); } } }
?连接池的大小应该根据系统的空闲状况灵活的改变连接的数量。比如请求高峰到来时,池中的连接数可能已经到了最大值,系统总是维持这么多的连接是很消