日期:2014-05-16 浏览次数:20699 次
以前写一些作业性质的网站,在对数据库操作时,都会写一个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("读取属性文件出错. ");
}
}
}
?连接池的大小应该根据系统的空闲状况灵活的改变连接的数量。比如请求高峰到来时,池中的连接数可能已经到了最大值,系统总是维持这么多的连接是很消