首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > JAVA > J2EE开发 >

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

2012-07-25 
自己第一次动手写数据库连接池,求指正由于使用 MongoDB,不能用传统的c3po,DBCP等连接池,所以自己DIY一个简

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

  由于使用 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 .....} 




 
接着定义了一个连接池管理器:

 
Java code
 package com.rooyeetone.vhost.db;import java.net.UnknownHostException;import com.mongodb.Mongo;import com.mongodb.MongoException;import com.rooyeetone.vhost.db.config.ResourceConfigFactory;/** * @author <a href="mailto:amoszhou@foxmail.com">周美华</a> * 功能描述:连接池管理 器 * @Since Jan 10, 2011 * */public class DBConnectionManager {        private static DBConnectionManager manager = null;    private static DBConnectionPool pool = null;        private static ResourceConfigFactory factory = null;            private DBConnectionManager(){}            public static synchronized DBConnectionManager getInstance(){        if(null == manager){            manager = new DBConnectionManager();        }        init();        return manager;    }            /**     *       * @author <a href="mailto:amoszhou@foxmail.com">周美华</a>     * 功能描述: 暴露给对外的接口     * @Since Jan 11, 2011     * @return     * @throws UnknownHostException     * @throws MongoException     */    public  static Mongo getDBConnection() throws UnknownHostException, MongoException{        getInstance();        //System.out.println("pool"+manager.getPool());        //System.out.println("pool"+manager.getPool().getConnection());//        Thread thread = Thread.currentThread();//        try {//            thread.sleep(2000);//        } catch (InterruptedException e) {//            // TODO Auto-generated catch block//            e.printStackTrace();//        }        Mongo mongo =pool.getConnection();        return mongo;    }             /**     *      * @author <a href="mailto:amoszhou@foxmail.com">周美华</a>     * 功能描述:创造边接池     * @Since Jan 10, 2011     * @param props     */    private static void createPool(){        if(factory.getMinConnCount().equals(0)  || factory.getMaxConnCount().equals(0)){            pool = new DBConnectionPool(factory.getMongoIp(),factory.getMongoPort());        }else{            pool = new DBConnectionPool(factory.getMongoIp(),factory.getMongoPort(),                    factory.getMinConnCount(),factory.getMaxConnCount(),null);        }    }        /**     * @author <a href="mailto:amoszhou@foxmail.com">周美华</a>     * 功能描述:释放所有资源     * @Since Jan 10, 2011     */    public static void release(Mongo mongo){        getInstance();        pool.freeConnection(mongo);    }        /**     *      * @author <a href="mailto:amoszhou@foxmail.com">周美华</a>     * 功能描述:初始化参数     * @Since Jan 11, 2011     */    public static void init(){        factory = ResourceConfigFactory.getInstance();        createPool();    }    private DBConnectionPool getPool() {        return pool;    }}





[解决办法]
用 DBCP、C3P0 的时候,JDBC 的操作除了连接获得的方式不一样之外,与不用这些池的操作完全是一样的,这样能才达到连接池的效果。

设计的东西应当按照 JDBC 标准来走,并不能因为使用了这个连接池而得把既有的代码结构改掉。

另外,一般来说连接池应当实现 javax.sql.DataSource 接口。
[解决办法]
感觉华哥应该简单的介绍一下MongoDB这个数据库。
[解决办法]

[解决办法]
连接池一般还需要使用动态代理来处理回收连接
[解决办法]
赞一下,自己写连接池,我以前也这么做过,后来发现不少开源社区已经有现成的了,对比后,还是直接 用开源的连接池.
HOHO,我这是避免重复发明轮子:)
不过楼主,如果你这轮子比现存的轮子好的话,还是值得的.
[解决办法]
很好很强大

热点排行