日期:2014-05-16  浏览次数:20539 次

定义自己的数据库连接池

这是一个很老的问题-数据库连接池,很多实际开发中都封装了自己的数据库连接访问机制,而数据库连接池是对数据库资源连接利用的一种更有效的管理方式,特别是资源的频繁分配﹑释放的问题。


数据库连接池的实现原理就是为数据库连接建立一个“缓冲池”,预先在这个"缓冲池"中放入一定数量的数据库连接,当我们需要连接时,就从“缓冲池”中取出一个连接,使用完毕之后再放回“缓冲池”中。同时我们通过设置"缓冲池"的最大个数来防止系统无穷无尽地与数据库连接。


在开源世界里,也有很多非常优秀的连接池,例如:C3P0,DBCP,proxool,DBPool等。


下面是本人写的一个非常简单的数据库连接池的实现,主要是体会一下数据库连接池的实现原理!

1.数据库连接池的实现类:

package org.hnylj.db.pool;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 定义自己的数据库连接池
 * @编写者:hnylj
 * 
 */
public class DbConnectionPool {

	private List<Connection> pool;
    private int poolSize;
    private Connection conn = null;
    private static DbConnectionPool instance = null;

    /** 
     * 单粒模式
     * 私有构造方法,获得本类的对象,通过getIstance方法。
     */
    private DbConnectionPool() {
    	pool = new ArrayList<Connection>(poolSize);
        this.createConnection();
    }
    
    /**
     * 得到当前连接池的一个实例
     */
    public static DbConnectionPool getInstance() {
        if (instance == null) {
            instance = new DbConnectionPool();
        }
        return instance;
    }
    
    /**
     * 得到连接池中的一个连接
     */
    public synchronized Connection getConnection() { 
        if (pool.size() > 0) {
            Connection conn = pool.get(0);
            pool.remove(conn);
            return conn;
        } else {
            return null;
        }
    }
    
    /**
     * 创建初始的数据库连接
     */
    private void createConnection() {
        Map<String,String> dbConfig = DbConfig.readDbConfigInfo();
        this.poolSize = Integer.parseInt(dbConfig.get("poolSize"));
        for (int i = 0; i < poolSize; i++) {
            try {
            	Class.forName((String)dbConfig.get("driver"));
                conn = DriverManager.getConnection((String)dbConfig.get("url"), (String)dbConfig.get("username"), (String)dbConfig.get("password"));
                pool.add(conn);
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
    
    /**
     * 用完将连接放回到连接池中
     * @param conn
     */
    public synchronized void release(Connection conn) {
        pool.add(conn);
    }

    /** 
     * 关闭连接池中的所有连接
     */
    public synchronized void closePool() {
        for (int i = 0; i < pool.size(); i++) {
            try {
                conn = ((Connection) pool.get(i));
                conn.close();
                pool.remove(i);
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) throws Exception  {
    	System.out.println(new DbConnectionPool().getConnection());
    }
}

?2.数据库连接配置类:

package org.ylj.db.pool;

import java.io.FileInputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

/**
 * 读取数据库配置信息
 * @编写者:hnylj
 *
 */
public class DbConfig {
	/**
	 * 读取数据库配置信息,以Key-Value对形式返回
	 * @return 
	 */
	public static Map<String,String> readDbConfigInfo() {
		Map<String,String> dbConfigMap = new HashMap<String,String>();
		try {
            String path = System.getProperty("user.dir") + "\\dbConfig.properties";
            FileInputStream is = new FileInputStream(path);
            Properties props = new Properties();
            props.load(is);
            dbConfigMap.put("driver", props.getProperty("driver"));
            dbConfigMap.put("username", props.getProperty("username"));
            dbConfigMap.put("password", props.getProperty("password"));
            dbConfigMap.put("url", props.getProperty("url"));
            dbConfigMap.put("poolSize", props.getProperty("poolSize"));
        } catch (Excepti