写过一些程序,在代码中经常会用到JDBC的数据库连接,但经常有人说在创建数据库连接是很耗系统资源的一件事。在网上找到很多解决方案,虽然可以用dbutils,Hibernate,tomcat数据库连接池等方法来减小系统消耗,为了锻炼自己的编程能力和对设计模式的理解,决定自己动手写一个连接池:
1.新建一个文件dbpool.properties
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/db_test
username=root
password=123456
poolSize=1
2.新建一个java类ConnectionPool
import java.io.FileInputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;
import java.util.Vector;public class ConnectionPool{
private String driverClassName;
private String url;
private String username;
private String password;
private int poolSize = 1; //连接池大小
private Vector<Connection> pool;
private static ConnectionPool instance = null;
/**
* 私有的构造方法,禁止外部创建本类的对象,要想获得本类的对象,通过getInstance()
* 方法获得获得对象 使用了设计模式中的单子模式
*/
private ConnectionPool(){
init();
}/**
* 连接池初始化
*/
private void init() {
pool = new Vector<Connection>(poolSize);
readConfig();
addConns();
}
/**
* 通过连接池 获得一个连接
*/
public synchronized Connection getConn(){
if(pool.size()>0){
Connection conn = pool.get(0);
pool.remove(conn);
return conn;
}else{
return null;
}
}
/**
* @param 释放连接 到连接池
*/
public synchronized void release(Connection conn){
pool.add(conn);
}
/**
* 关闭池中所有连接
*/
public synchronized void closePool(){
for(int i=0;i<pool.size();i++){
try {
pool.get(i).close();
} catch (SQLException e) {
e.printStackTrace();
}
pool.remove(i);
}
}
/**
* @return 返回当前连接池的一个对象
*/
public static ConnectionPool getInstance(){
if(instance==null){
instance = new ConnectionPool();
}
return instance;
}
/**
* 初始化连接池中的连接
*/
private void addConns() {
Connection conn = null;
try {
Class.forName(driverClassName);
for(int i=0;i<poolSize;i++){
conn = DriverManager.getConnection(url,username,password);
pool.add(conn);
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 读取配置文件
*/
private void readConfig() {
String path = System.getProperty("user.dir")+"\\dbpool.properties";
try {
FileInputStream is = new FileInputStream(path);
Properties props = new Properties();
props.load(is);
driverClassName = props.getProperty("driverClassName");
url = props.getProperty("url");
username = props.getProperty("username");
password = props.getProperty("password");
poolSize = Integer.parseInt(props.getProperty("poolSize"));
} catch (Exception e) {
e.printStackTrace();
System.out.println("读取配置文件出错");
}
}
}
3.编写测试类ConnectionPoolTest,比较循环100次使用连接池的时间与直接获取连接的时间
package webbook.util;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
public class ConnectionPoolTest {
public static void main(String[] args) throws Exception {
String sql = "select id,name,phone from guestbook";
long start = System.currentTimeMillis();
ConnectionPool pool = null;
for (int i = 0; i < 100; i++) {
pool = ConnectionPool.getInstance();
Connection conn = pool.getConnection();
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(sql);
while (rs.next()) {
}
rs.close();
stmt.close();
pool.release(conn);
}
pool.closePool();
System.out.println("经过100次的循环调用,使用连接池花费的时间:" + (System.currentTimeMillis() - start) + "ms\n");
String hostName = "192.168.1.20";
String driverClass = "oracle.jdbc.driver.OracleDriver";
String url = "jdbc:oracle:thin:@" + hostName + ":1521:ora9";
String user = "scott";
String password = "tiger";
start = System.currentTimeMillis();
Class.forName(driverClass);
for (int i = 0; i < 100; i++) {
Connection conn = DriverManager.getConnection(url, user, password);
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(sql);
while (rs.next()) {
}
rs.close();
stmt.close();
conn.close();
}
System.out.println("经过100次的循环调用,不使用连接池花费的时间:" + (System.currentTimeMillis() - start) + "ms");
}
}
通过比较使用连接池确实比直接获取连接快很多...