`
pterodactyl
  • 浏览: 751195 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

Commons pool 数据库连接池实现

    博客分类:
  • java
阅读更多

  Commons pool 数据库连接池实现 收藏
1,首先我们要实现一个工厂类,用于处理验证,创建对象等方法。

view plaincopy to clipboardprint?
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;  
        }  
    }  
 

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 操作类

view plaincopy to clipboardprint?
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);  
    }  
      
      
 

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 函数

 view plaincopy to clipboardprint?
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();  
        }  
 
    }  
 

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  方法,释放对象。

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

http://blog.csdn.net/keyboardsun

作者 keyboardsun

 

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/keyboardsun/archive/2009/06/17/4277592.aspx

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics