说到数据库连接池也是初学者会望而却步,认为是如何高深莫测的东西,其实可以用一句话来解释: 连接池的出现是为了用户频繁访问数据库而造成速度和性能上的迟缓才对访问数据库的方法作了一点修改,这个修改就是把原本要关闭的Connection对象放到Collection集合里以重复利用。下面,我就来自己写一个数据库的连接池,看看他到底有多“神奇”(为了简单起见,以下代码都没有加导入包,读者可利用Eclipse的自动导入方式导入):
首先,我们先创建一个接口,此接口很简单,就是提供一个获得连接和一个关闭连接的方法:
public interface DBSource {
public Connection getConnection()throws SQLException;
public void closeConnection(Connection con)throws SQLException;
}
然后我们编写一个数据库连接池类实现DBSource 接口:
public class BasicDBSource implements DBSource {
private Properties pro;//属性对象 private String url;
private String user;
private String password;
private int max;//最大连接数 private List
public BasicDBSource()throws IOException,ClassNotFoundException{
this("myjdbc.properties");//调用带参的构造函数
}
public BasicDBSource(String configFile)throws IOException,ClassNotFoundException{
//获取属性文件,因为我将url,user,password,max,driver的属性值存放在一个myjdbc.properties的属性文件里
//这样设计的目的也是为了提高代码的低偶合度,为重构做些小小的贡献 pro=new Properties();
pro.load(new FileInputStream(configFile));
url=pro.getProperty("url");
user=pro.getProperty("user");
password=pro.getProperty("password");
max=Integer.parseInt(pro.getProperty("poolmax"));
Class.forName(pro.getProperty("driver"));
connections=new ArrayList
}
public synchronized void closeConnection(Connection con) throws SQLException {
//如果集合中的Connection对象个数大于等于允许的最大连接数,则关闭连接
//否则,将要关闭的Connection对象放入集合栈中,等需要连接时再弹出 if (connections.size()>=max) {
con.close();
} else {
connections.add(con);
}
}
public synchronized Connection getConnection() throws SQLException {
//要获取连接时,先判断集合栈中是否存有压入的Connection对象,如果没有,则像原来一样创建连接
//如果有,则弹出集合栈中的Connection对象,无需再行连接 if (connections.size()==0) {
return DriverManager.getConnection(url,user,password);
} else {
int last=connections.size()-1;
return connections.remove(last);
}
}
}
最后,我们写一个测试类,来测试一下结果:
public class ConnectionPoolDemo {
public static void main(String[] args) {
try {
DBSource dbsource=new BasicDBSource();
Connection con1=dbsource.getConnection();
dbsource.closeConnection(con1);
Connection con2=dbsource.getConnection();
dbsource.closeConnection(con2);
System.out.println(con1==con2);
} catch (IOException e) {
e.printStackTrace();
}
catch (ClassNotFoundException e) {
e.printStackTrace();
}
catch (SQLException e) {
e.printStackTrace();
}
}
}测试结果为:true
也就是说con1对象和con2对象是同一个对象,说明在连接数据库时是将集合中的连接对象赋予请求连接的对象(集合非空),而不用每次访问都先去连接数据库。
以上的实例只是为了让大家明白数据库连接池的原理,当然在网上有许多优秀的连接池原码可以拿来就用,大家也可以参考一下。
联系客服