Commons pool 数据库连接池实现

 

1,首先我们要实现一个工厂类,用于处理验证,创建对象等方法。

 

package net.chinacsharp.jdf.pool.connectionpool; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import org.apache.commons.pool.PoolableObjectFactory; /** * @author keyboardsun mail: keyboardsun@163.com * @site http://www.chinacsharp.net */ public class SecObjectFactory implements PoolableObjectFactory { // private ConnectionGetter connectionGetter = new ConnectionGetter(); // private String CONNECTION_NAME="Sec"; /** * 这里,我们在使用对象的时候,需要首先激活这个对象,但是在多线程情况下, * 这个对象已经被别的线程借去用了,那我们就要再建立一个对象。 */ public void activateObject(Object arg0) throws Exception { System.out.println("activateObject"+arg0); } /** * 这里我们销毁这个对象。不用这个对象了,这个方法得在业务使用过程中主动调用。 * 在调用完这个方法过后,对象已经被销毁,但是在Object pool里面还是存在这个对象的 * 只是这个对象是null而已。所以在调用完destroyObject过后,要记得把pool清空一下。 */ public void destroyObject(Object arg) throws Exception { System.out.println("destroyObject:"+arg); if(((Connection)arg).isClosed()!=true){ ((Connection)arg).close(); } } /** * 这里,在业务中第一次借对象的时候,这里要初始化一个,如果初始的都被借了,那就要继续初始 * 这里创建的对象将被存到pool里面 */ public Object makeObject() throws Exception { Class.forName("com.mysql.jdbc.Driver").newInstance(); Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "admin"); conn.setAutoCommit(false); // Object o = connectionGetter.getNewConnection(CONNECTION_NAME); // System.out.println("makeObject:"+o); return conn; } /** * 这里,在我们使用完每个对象过后,要做的就是归还,在归还后就要调用这个方法。 * 简单的说,在还款凭证上面签个大名 */ public void passivateObject(Object arg0) throws Exception { System.out.println("passivateObject"+arg0); } /** *这个方法是验证对象,这里我们不做处理,这里在借对象和还对象的时候都要验证下的。 */ public boolean validateObject(Object arg) { System.out.println("validateObject:"+arg); try { if(((Connection)arg).isClosed()==true){ return false; } else { return true; } } catch (SQLException e) { e.printStackTrace(); return false; } } }

 

2,我们要做一个pool 操作类

 

package net.chinacsharp.jdf.pool.connectionpool; import org.apache.commons.pool.ObjectPool; import org.apache.commons.pool.PoolableObjectFactory; import org.apache.commons.pool.impl.GenericObjectPool; import org.apache.commons.pool.impl.StackObjectPool; import org.apache.commons.pool.impl.GenericObjectPool.Config; public class SecObjectPool implements ObjectPool{ private static SecObjectFactory factory = new SecObjectFactory(); private static ObjectPool pool = null; private static GenericObjectPool.Config config = null; private static boolean initFlag = false;//是否初始化 static { if(!initFlag){ config = new Config(); config.maxActive = 2; //这个属性没啥用 config.maxIdle = 5; //最大连接数,就这个有用. config.minIdle = 3; //最少连接数 ,这个也没用,哈哈. pool = new GenericObjectPool(factory,config); initFlag = true; } } public Object borrowObject() throws Exception { return pool.borrowObject(); } public void returnObject(Object arg0) throws Exception { pool.returnObject(arg0); } public void invalidateObject(Object arg0) throws Exception { pool.invalidateObject(arg0); } public void addObject() throws Exception { pool.addObject(); } public int getNumIdle() throws UnsupportedOperationException { return pool.getNumIdle(); } public int getNumActive() throws UnsupportedOperationException { return pool.getNumActive(); } public void clear() throws Exception, UnsupportedOperationException { pool.clear(); } public void close() throws Exception { pool.close(); } public void setFactory(PoolableObjectFactory arg0) throws IllegalStateException, UnsupportedOperationException { pool.setFactory(arg0); } }

 

3,Main 函数

 import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import net.chinacsharp.jdf.pool.connectionpool.*; public class PoolTest { /** * @param args * @throws SQLException */ public static void main(String[] args) throws SQLException { SecObjectPool p = new SecObjectPool(); Connection connection = null; try { connection = (Connection) p.borrowObject(); PreparedStatement statement = null; statement = connection.prepareStatement("SELECT * FROM PERSON"); ResultSet rs = statement.executeQuery(); rs.close(); System.out.println("================"); p.addObject(); System.out.println("使用中几个:"+p.getNumActive()); System.out.println("队列中还有:"+p.getNumIdle()); p.addObject(); p.addObject(); p.addObject(); p.addObject(); connection = (Connection) p.borrowObject(); connection = (Connection) p.borrowObject(); connection = (Connection) p.borrowObject(); p.addObject(); p.addObject(); p.addObject(); p.addObject(); System.out.println("使用中几个:"+p.getNumActive()); System.out.println("队列中还有:"+p.getNumIdle()); System.out.println("================"); p.returnObject(connection); System.out.println("使用中几个:"+p.getNumActive()); System.out.println("队列中还有:"+p.getNumIdle()); System.out.println("=====clear==========="); p.clear(); System.out.println("=====close==========="); p.close(); } catch (Throwable e) { e.printStackTrace(); connection.close(); } } }

 

4,输出结果

 

activateObjectcom.mysql.jdbc.Connection@147ee05
================
passivateObjectcom.mysql.jdbc.Connection@1960f05
使用中几个:1
队列中还有:1
passivateObjectcom.mysql.jdbc.Connection@1e04cbf
passivateObjectcom.mysql.jdbc.Connection@66e815
passivateObjectcom.mysql.jdbc.Connection@edc3a2
passivateObjectcom.mysql.jdbc.Connection@6e70c7
activateObjectcom.mysql.jdbc.Connection@1960f05
activateObjectcom.mysql.jdbc.Connection@1e04cbf
activateObjectcom.mysql.jdbc.Connection@66e815
passivateObjectcom.mysql.jdbc.Connection@1d63e39
passivateObjectcom.mysql.jdbc.Connection@d0a5d9
passivateObjectcom.mysql.jdbc.Connection@b8f82d
passivateObjectcom.mysql.jdbc.Connection@a6aeed
destroyObject:com.mysql.jdbc.Connection@a6aeed
使用中几个:4
队列中还有:5
================
passivateObjectcom.mysql.jdbc.Connection@66e815
destroyObject:com.mysql.jdbc.Connection@66e815
使用中几个:3
队列中还有:5
=====clear===========
destroyObject:com.mysql.jdbc.Connection@edc3a2
destroyObject:com.mysql.jdbc.Connection@6e70c7
destroyObject:com.mysql.jdbc.Connection@1d63e39
destroyObject:com.mysql.jdbc.Connection@d0a5d9
destroyObject:com.mysql.jdbc.Connection@b8f82d
=====close===========

 

通过以上结果我们可以发现,在连接池clear()的时候,调用 destroyObject 方法,我们这里把连接都关闭了

同样的道理,我们close()的时候也是如此。

 

而连接池的最大激活数目的设置是不起作用的,但是队列最多连接数那是有效果的,如果队列已经是最多了,它会把创建的或者归还的,调用 destroyObject  方法,释放对象。

 

原创作品,转载请标明出处

作者 keyboardsun

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值