自己第一次动手写数据库连接池,求指正
由于使用 MongoDB,不能用传统的c3po,DBCP等连接池,所以自己DIY一个简单的,mongoDB真的连接上数据库,就是通过
Mongo mongo = new Mongo(ip,[port]) 来进行连接的.... 至于连那个库,其实他只是从库的 Map里面,通过调用get()方法进行获取。。
首先写了一个连接池的类:DBConnectionPool
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 .....}
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; }}