自个儿第一次动手写数据库连接池,求指正

   阅读
自己第一次动手写数据库连接池,求指正

  由于使用 MongoDB,不能用传统的c3po,DBCP等连接池,所以自己DIY一个简单的,mongoDB真的连接上数据库,就是通过
Mongo mongo = new Mongo(ip,[port]) 来进行连接的.... 至于连那个库,其实他只是从库的 Map里面,通过调用get()方法进行获取。。

  首先写了一个连接池的类:DBConnectionPool

Java code


package com.rooyeetone.vhost.db;

import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import com.mongodb.Mongo;
import com.mongodb.MongoException;
import com.rooyeetone.vhost.utils.BlankUtil;

/**
 * @author <a href="mailto:amoszhou@foxmail.com">周美华</a>
 * 功能描述:mongoDB数据库连接池
 * @Since Jan 10, 2011
 *
 */
public class DBConnectionPool {

    
    /**
     * mongoDB连接必须的参数
     */
    private String dbIp;     
    private Integer dbPort; 
    private Integer refreshTime;
    private static final Integer defaultRefreshTime = 60 * 60 * 1000; //默认刷新连接池
    
    /**
     * 连接池的参数
     */
    private static List<Mongo>  freeConnections = new ArrayList<Mongo>(); //空闲连接  
    private static Integer inUsed = 0;                                      //已用连接数
    private Integer minConnCount;                                 //连接池中保持的最小连接数
    private Integer maxConnCount;                                   //连接池中保持的最大连接数
    private static final Integer defaultConnCount = 3;             //默认连接数
    
    
    private Timer timer;
    
    



    /**
     * empty constructor
     */
    public DBConnectionPool() {
        super();
    }


    
    
    /**
     * constructor 
     * @param dbIp
     * @param dbPort
     * @param dbName
     */
    protected DBConnectionPool(String dbIp, Integer dbPort) {
        this(dbIp,dbPort,0,0,defaultRefreshTime);
    }





    

    /**
     * full option construtor
     * @param dbIp
     * @param dbPort
     * @param dbname
     * @param minConnCount
     * @param maxConnCount
     * @param dbUsername
     * @param dbPassword
     */
    protected DBConnectionPool(String dbIp, Integer dbPort, 
            Integer minConnCount, Integer maxConnCount,Integer refreshTime) {
        super();
        this.dbIp = dbIp;
        this.dbPort = dbPort;
        this.minConnCount = (minConnCount == null ? defaultConnCount : minConnCount);
        this.maxConnCount = (maxConnCount == null ? 0 : maxConnCount);
        this.refreshTime = (refreshTime == null ? defaultRefreshTime
                : refreshTime);
        
        //每60分钟,自动刷新连接池中的连接
        timer = new Timer(true);
        timer.schedule(new TimerTask(){
            @Override
            public void run() {
                try {
                    releaseAllConn();
                    createConnection();
                } catch (UnknownHostException e) {
                    e.printStackTrace();
                } catch (MongoException e) {
                    e.printStackTrace();
                }
            }},this.refreshTime,this.refreshTime);
    }



    /**
     * 
     * @author <a href="mailto:amoszhou@foxmail.com">周美华</a>
     * @Description   free connection
     * @Since Jan 10, 2011
     * @param mongo
     */
    public  void freeConnection(Mongo mongo){
        
        if(null != mongo){
            freeConnections.add(mongo);
            inUsed -- ;
        }
        System.out.println("[free Connection]-----> free size  ====" + freeConnections.size() + "   and in used =======" + inUsed);
    }

    
    
    /**
     * 
     * @author <a href="mailto:amoszhou@foxmail.com">周美华</a>
     * 功能描述: 获取连接
     * @Since Jan 10, 2011
     * @return
     * @throws UnknownHostException
     * @throws MongoException
     */
    public synchronized  Mongo getConnection() throws UnknownHostException, MongoException{
        Mongo mongo = null;
        synchronized(freeConnections){
            
            if(BlankUtil.isBlank(freeConnections)){
                //产生,并获取连接
                createConnection();
            }
            
            //连接池已经消耗完,临时办法:将最大连接数增大10个
            if(freeConnections.size() == 0){
                this.maxConnCount =  this.maxConnCount + 10;
                createConnection();
            }
            mongo = freeConnections.get(0);
            //从空闲连接池中移除,并确保获取到无论效连接以后来,递归获取时不是重复的连接
            freeConnections.remove(0);
            //连接无效,递归获取
            if(null == mongo){
                getConnection();
            }
            createConnection();

            inUsed++;
        }
        
        System.out.println("[get Connection]-----> free size  ====" + freeConnections.size() + "   and in used =======" + inUsed);
        return mongo;
    }


    /**
     * 
      * @author <a href="mailto:amoszhou@foxmail.com">周美华</a>
     * 功能描述:释放全部链接
     * @Since Jan 10, 2011
     */
    public synchronized void releaseAllConn(){
        Iterator<Mongo> it = freeConnections.iterator();
        while(it.hasNext()){
            it.next().close();
        }
        freeConnections.clear();
    }
    
    
    
    /**
     * 
      * @author <a href="mailto:amoszhou@foxmail.com">周美华</a>
     * 功能描述: 产生连接数,并置入空闲连接池
     * @Since Jan 10, 2011
     * @throws UnknownHostException
     * @throws MongoException
     */
    private synchronized void createConnection() throws UnknownHostException, MongoException{
        
        Integer mincount = 0;
        
        //未配置最少连接数
        if(this.minConnCount <= 0){
            mincount = defaultConnCount;
        }else{
            mincount = this.minConnCount;
        }
        //空闲的连接数
        Integer freeConnectionCount = freeConnections.size();
        
        //判断还需要产生多少个连接数
        Integer needCreateCount = 0 ;
        if(mincount>freeConnectionCount && (freeConnectionCount + inUsed) < (this.maxConnCount-1)){
            Integer canCreate = this.maxConnCount - freeConnectionCount - inUsed;
            if(mincount - freeConnectionCount > canCreate){
                needCreateCount = canCreate <= 0 ? 0 : canCreate;
            }else{
                needCreateCount = mincount - freeConnectionCount;
            }
        }

        //先校验IP地址和端口
        validateDB();
        
        //产生链接放入空闲连接池
        for(int i = 0; i < needCreateCount; i++ ){
            Mongo mongo = new Mongo(this.dbIp,this.dbPort);
            freeConnections.add(mongo);
        }
        System.out.println("[create Connection]-----> free size  ====" + freeConnections.size() + "   and in used =======" + inUsed);
    }
    
    
    /**
     * 
      * @author <a href="mailto:amoszhou@foxmail.com">周美华</a>
     * 功能描述:校验ip地址 和 端口号
     * @Since Jan 10, 2011
     * @throws UnknownHostException
     */
    private void validateDB() throws UnknownHostException{
        //没ip地址
        if(BlankUtil.isBlank(this.dbIp)){
            throw new UnknownHostException("数据库地址不能为空");
        }
        
        //有填端口号时
        if(!BlankUtil.isBlank(this.dbPort)){
            if(this.dbPort<0 || this.dbPort> 65535){
                throw new IllegalArgumentException("端口必须是0~65535之间的整数");
            }
        }else{
            this.dbPort = 27017;
        }
    }
    
    //getter and setter .....
}



阅读