zoukankan      html  css  js  c++  java
  • JDBC 连接池代码

    package com.mark.human.db;

    import java.sql.*;
    import java.lang.reflect.*;

    import org.omg.CORBA.portable.InvokeHandler;


    import freemarker.template.utility.ObjectConstructor;

    /**
     * 定义数据库连接的代理类
     * @author mark
     *
     */
    public class ConnectionProxy implements InvocationHandler {

     //定义连接
     private Connection conn=null;   
        //定义监控连接创建的语句
     private Statement statRef=null;         
     private PreparedStatement preStatRef=null;
        //是否支持事务标志
     private boolean supportTransaction = false;
     //数据库的忙状态
     private boolean isFree=false;
        //最后一次访问时间
     long lastAccessTime = 0;
        //定义要接管的函数的名字
     String CREATESTATE="createStatement";
     String CLOSE="close";
     String PREPARESTATEMENT="prepareStatement";
     String COMMIT="commit";
     String ROLLBACK="rollbakc";
     
     /**
      * 构造函数,采用私有,防止被直接创建 
      * @param param 连接参数
      */
        private ConnectionProxy(ConnectionParam param) {
      //记录日志
         try{
          //创建连接
       Class.forName("oracle.jdbc.driver.OracleDriver");
       conn=DriverManager.getConnection("jdbc:oracle:thin:@10.8.1.234:1521:WF4PPDB","PP42","PP42");
          DatabaseMetaData dm=null;
          dm=conn.getMetaData();
             //判断是否支持事务
          supportTransaction=dm.supportsTransactions();
         }catch(Exception ex){
          ex.printStackTrace();
         }
     }
     
        /**
        * (non-Javadoc) 
        * @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[]) 
        */
        public Object invoke(Object proxy, Method method, Object[] args)  throws Throwable{
      Object obj=null;
            //判断是否调用了close的方法,如果调用close方法则把连接置为无用状态 
         if(CLOSE.equals(method.getName())){
          //设置不使用标志
          setFree(false);
          if(statRef!=null)
           statRef.close();
          if(preStatRef!=null)
           preStatRef.close();
         
          return null;
         }
        
            //判断是使用了createStatement语句
         if(CREATESTATE.equals(method.getName())){
          try{
          obj=method.invoke(conn, args);
          statRef = (Statement)obj;
          return obj;
          }catch(ClassCastException ex){
           ex.printStackTrace();
          }
         }
        
         //判断是使用了prepareStatement语句
         if (PREPARESTATEMENT.equals(method.getName())) {   
          obj = method.invoke(conn, args);   
          preStatRef = (PreparedStatement)obj;   
          return obj;  
         } 
        
           //如果不支持事务,就不执行该事物的代码 
         if((COMMIT.equals(method.getName())||ROLLBACK.equals(method.getName()))&&(!isSupportTransaction())){
          return null;
         }
        
         obj=method.invoke(conn, args);
        
            //设置最后一次访问时间,以便及时清除超时的连接
         lastAccessTime=System.currentTimeMillis();
        
         return obj;
        }
       
        /** 
        * 创建连接的工厂,只能让工厂调用 
        * @param factory 要调用工厂,并且一定被正确初始化 
        * @param param 连接参数 
        * @return 连接 
        */
        public static ConnectionProxy getConnection(ConnectionFactory factory,ConnectionParam param){
            //判断是否正确初始化的工厂
         if(factory.isCreate()){
       ConnectionProxy _conn=new ConnectionProxy(param);
       return _conn;
      }else{
       return null;
      }
        
        }
       
       
        public Connection getFreeConnection(){
         //返回数据库连接conn的接管类,以便截住close方法
         Connection cn=(Connection)Proxy.newProxyInstance(conn.getClass().getClassLoader(), conn.getClass().getInterfaces(), this);
         return cn;
        }
       
        /** 
        * 该方法真正的关闭了数据库的连接 
        * @throws SQLException
        */
        public void close() throws SQLException{
            //由于类属性conn是没有被接管的连接,因此一旦调用close方法后就直接关闭连接
         conn.close();
        }
     
     
     public void setFree(boolean isFree) {
      this.isFree = isFree;
     }

     public boolean isFree() {
      return isFree;
     }
     
     /** 
     * 判断是否支持事务 
     * @return boolean 
     */
     public boolean isSupportTransaction(){ 
      return supportTransaction;
     }
    }
     

    ===================================================================================

    package com.mark.human.db;

    import java.sql.Connection;
    import java.sql.SQLException;
    import java.util.*;

    /**
     *
     * @author mark
     *
     */
    public class ConnectionFactory {

     private static ConnectionFactory m_instance = null;

     // 在使用的连接池
     private LinkedHashSet ConnectionPool = null;

     // 空闲连接池
     private LinkedHashSet FreeConnectionPool = null;

     // 最大连接数
     private int MaxConnectionCount = 10;

     // 最小连接数S
     private int MinConnectionCount = 2;

     // 当前连接数
     private int current_conn_count = 0;

     // 连接参数
     private ConnectionParam connparam = null;

     // 是否创建工厂的标志
     private boolean isflag = false;

     // 是否支持事务
     private boolean supportTransaction = false;

     // 定义管理策略
     private int ManageType = 0;
     
     /**
      * 构造器
      */
     private ConnectionFactory() {
     
      ConnectionPool = new LinkedHashSet();
      FreeConnectionPool=new LinkedHashSet();
     }

     /**
      * 使用指定的参数创建一个连接池 
      * @throws SQLException
      */
     public ConnectionFactory(ConnectionParam param,FactoryParam fparam) throws SQLException {
      if((param==null)||(fparam==null))
       throw new SQLException("ConnectionParam和FactoryParam不能为空");
     
      if(m_instance==null){
       synchronized (ConnectionFactory.class) {
        if(m_instance==null){
         //参数定制
         m_instance=new ConnectionFactory();
         connparam=param;
         m_instance.MaxConnectionCount=fparam.getMaxConnectionCount();
         m_instance.MinConnectionCount=fparam.getMinConnectionCount();
         m_instance.ManageType=fparam.getManageType();
         m_instance.isflag=true;
        
         //初始化,创建MinConnectionCount个连接    
         System.out.println("connection factory 创建!");  
         try{
          for(int i=0;i<m_instance.MinConnectionCount;i++){
           ConnectionProxy conn=ConnectionProxy.getConnection(m_instance, m_instance.connparam);
           if(conn==null)
            continue;
           System.out.println("connection创建");
           m_instance.FreeConnectionPool.add(conn);
                                //加入空闲连接池
           m_instance.current_conn_count++;
           //标志是否支持事务
           m_instance.supportTransaction=conn.isSupportTransaction();
          }
         }catch(Exception ex){
          ex.printStackTrace();
         }
        
                        //根据策略判断是否需要查询 
         if(m_instance.ManageType!=0){
          Thread t=new Thread(new FactoryManageThread(m_instance));
          t.start();
         }
        }
       }
      }
     }
     
     /** 
     * 标志工厂是否已经创建 
     * @return boolean 
     */ 
     public boolean isCreate() {
      return m_instance.isflag;
     } 
     
     /**
      * 从连接池中取一个空闲的连接
      * @return Connection 
      * @throws SQLException
      */
     public synchronized Connection getFreeConnection() throws SQLException{
      Connection cn=null;
            //获取空闲连接
      Iterator ir=m_instance.FreeConnectionPool.iterator();
      while(ir.hasNext()){
       ConnectionProxy conn=(ConnectionProxy)ir.next();
       //找到未用的连接
       if(!conn.isFree()){
        cn=conn.getFreeConnection();
        conn.setFree(true);
        //移出空闲区
        m_instance.FreeConnectionPool.remove(conn);
       
        //加入连接池
        m_instance.ConnectionPool.add(conn);
        break;
       }
      }
     
      //检查空闲池是否为空 
      if(m_instance.FreeConnectionPool.isEmpty()){
       //再检查是否能够分配 
       if(m_instance.current_conn_count<m_instance.MaxConnectionCount){
        //新建连接到空闲连接池
        int newCount=0;
        //取得要建立的数目  
        if(m_instance.MaxConnectionCount-m_instance.current_conn_count>=m_instance.MinConnectionCount){
         newCount=m_instance.MinConnectionCount;
        }else{
         newCount=m_instance.MaxConnectionCount-m_instance.current_conn_count;
        }
        //创建连接
        for(int i=0;i<newCount;i++){
         ConnectionProxy _conn=ConnectionProxy.getConnection(m_instance, connparam);
         m_instance.FreeConnectionPool.add(_conn);
         m_instance.current_conn_count++;
        }
       }else{
        //如果不能新建,检查是否有已经归还的连接
        ir=m_instance.ConnectionPool.iterator();
        while(ir.hasNext()){
         ConnectionProxy _conn=(ConnectionProxy)ir.next();
         if(!_conn.isFree()){
          cn=_conn.getFreeConnection();
          _conn.setFree(false);
          m_instance.ConnectionPool.remove(_conn);      
          m_instance.FreeConnectionPool.add(_conn);        
          break;
         }
        }
       }
      }
     
      //再次检查是否能分配连接
      if(cn==null){
       ir=m_instance.FreeConnectionPool.iterator();
       while(ir.hasNext()){
        ConnectionProxy _conn=(ConnectionProxy)ir.next();
        if(!_conn.isFree()){
         cn = _conn.getFreeConnection();    
         _conn.setFree(true);
         m_instance.FreeConnectionPool.remove(_conn);     
         m_instance.ConnectionPool.add(_conn);       
         break;
        }
       }
       if(cn==null)
        //如果不能则说明无连接可用
        throw new SQLException("没有可用的数据库连接");
      }
     
      System.out.println("Get Connection");
      return cn;
     }
     
     /** 
     * 关闭该连接池中的所有数据库连接 
     * @throws SQLException 
     */
     public synchronized void close() throws SQLException {
      this.isflag=false;
      SQLException sqlError=null;
      //关闭空闲池
      Iterator ir=m_instance.FreeConnectionPool.iterator();
      while(ir.hasNext()){
       try{
        ((ConnectionProxy)ir.next()).close();
        System.out.println("Close connection:Free");
        m_instance.current_conn_count--;
       }catch(Exception ex){
         if (ex instanceof SQLException) {
         sqlError=(SQLException)ex;
        }
       }
      }
     
      //关闭在使用的连接池
      ir=m_instance.ConnectionPool.iterator();
      while(ir.hasNext()){
       try{
        ((ConnectionProxy)ir.next()).close();
        System.out.println("Close connection:Using");
       }catch(Exception ex){
        if (ex instanceof SQLException) {
         sqlError=(SQLException)ex;
        }
       }
      }
     
      if(sqlError!=null)
       throw sqlError;
     }
     
     /**
     * 返回是否支持事务
     * @return boolean 
     */
     public boolean isSupportTransaction() {
      return m_instance.supportTransaction;
     }
     
     /**
      * 连接池调度管理
      *
      */
     public void schedule() {
      Connection cn=null;
      //再检查是否能够分配 
      Iterator ir=null;
      //检查是否有已经归还的连接
      ir=m_instance.ConnectionPool.iterator();
      while(ir.hasNext()){
       ConnectionProxy _conn=(ConnectionProxy)ir.next();
       if(!_conn.isFree()){
        cn=_conn.getFreeConnection();
        _conn.setFree(false);
        m_instance.ConnectionPool.remove(_conn);   
        m_instance.FreeConnectionPool.add(_conn); 
        break;
       }
      }
     
      if(m_instance.current_conn_count<m_instance.MaxConnectionCount){
       //新建连接到空闲连接池
       int newCount=0;
                //取得要建立的数目 
       if (m_instance.MaxConnectionCount - m_instance.current_conn_count >=m_instance.MinConnectionCount)  
       {   
        newCount = m_instance.MinConnectionCount;  
       }else{  
        newCount = m_instance.MaxConnectionCount - m_instance.current_conn_count;  
       }  
                //创建连接  
       for(int i=0;i<newCount;i++){
        ConnectionProxy _conn=ConnectionProxy.getConnection(m_instance, connparam);
        m_instance.FreeConnectionPool.add(_conn);
        m_instance.current_conn_count++;
       }
      }
     }
     
    }


    ================================================================================

    package com.mark.human.db;

    import java.io.Serializable;
    import com.mark.human.model.*;
    /**
     * 实现数据库连接的参数类
     * @author mark
     *
     */
    public class ConnectionParam implements Serializable {
     
     /**
      *
      */
     private static final long serialVersionUID = 1L;

     private String driver;     //数据库驱动程序
     private String url;        //数据连接的URL
     private String user;       //数据库用户名
     private String password;   //数据库密码      
     
     public String getDriver() {
      return driver;
     }
     public void setDriver(String driver) {
      this.driver = driver;
     }
     public String getPassword() {
      return password;
     }
     public void setPassword(String password) {
      this.password = password;
     }
     public String getUrl() {
      return url;
     }
     public void setUrl(String url) {
      this.url = url;
     }
     public String getUser() {
      return user;
     }
     public void setUser(String user) {
      this.user = user;
     }
     
     public ConnectionParam(String driver,String url,String user,String password){
      this.driver=driver;
      this.url=url;
      this.user=user;
      this.password=password;
     }
     
     /**
      * @see java.lang.Object#clone()
      */
     public Object clone(){
      ConnectionParam param=new ConnectionParam(driver,url,user,password);
      return param;
     }
     
     /** 
     * @see java.lang.Object#equals(java.lang.Object) 
     */
     public boolean equals(Object obj) {
       if (obj instanceof ConnectionParam) {
       ConnectionParam param=(ConnectionParam)obj;
       return ((driver.compareToIgnoreCase(param.getDriver()) == 0)&&(url.compareToIgnoreCase(param.getUrl()) == 0)&&(user.compareToIgnoreCase(param.getUser()) == 0)&&(password.compareToIgnoreCase(param.getPassword()) == 0)); 
      }
       return false;
     }
     
    }


    ============================================================================

    package com.mark.human.db;

    /**
     * 连接池调度线程
     *
     * @author mark
     *
     */
    public class FactoryManageThread implements Runnable {
     ConnectionFactory cf = null;

     long delay = 1000;

     public FactoryManageThread(ConnectionFactory obj) {
      cf = obj;
     }

     /*
      * (non-Javadoc)
      *
      * @see java.lang.Runnable#run()
      */
     public void run() {
      while (true) {
       try {
        Thread.sleep(delay);
       } catch (InterruptedException e) {
        e.printStackTrace();
       }
       System.out.println("run.....run.....");
       // 判断是否已经关闭了工厂,那就退出监听
       if (cf.isCreate())
        cf.schedule();
       else
        System.exit(1);
      }
     }
    }


    =================================================================================

    package com.mark.human.db;

    /**
     * 连接池工厂参数
     *
     * @author mark
     *
     */
    public class FactoryParam {
     // 最大连接数
     private int MaxConnectionCount = 4;

     // 最小连接数
     private int MinConnectionCount = 2;

     // 回收策略
     private int ManageType = 0;
     
     public FactoryParam(){}
     
     /** 
     * 构造连接池工厂参数的对象 
     * @param max 最大连接数 
     * @param min 最小连接数 
     * @param type 管理策略 
     */
     public FactoryParam(int max,int min,int type){
      this.MaxConnectionCount=max;
      this.MinConnectionCount=min;
      this.ManageType=type;
     }

     public int getManageType() {
      return ManageType;
     }

     public void setManageType(int manageType) {
      ManageType = manageType;
     }

     public int getMaxConnectionCount() {
      return MaxConnectionCount;
     }

     public void setMaxConnectionCount(int maxConnectionCount) {
      MaxConnectionCount = maxConnectionCount;
     }

     public int getMinConnectionCount() {
      return MinConnectionCount;
     }

     public void setMinConnectionCount(int minConnectionCount) {
      MinConnectionCount = minConnectionCount;
     }
    }


    ============================================================================

    package com.mark.human.db;

    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.sql.Statement;

    public class testPool {

     public void test1() {
      String user = "ppuser";
      String password = "ppuser";
      String url = "jdbc:oracle:thin:@192.168.0.1:1521:PPDATA";
      String driver = "oracle.jdbc.driver.OracleDriver";

      ConnectionParam param = new ConnectionParam(driver, url, user, password);
      ConnectionFactory cf = null;
      // new ConnectionFactory(param,new FactoryParam());
      try {
       cf = new ConnectionFactory(param, new FactoryParam());
       Connection conn1 = cf.getFreeConnection();
       Connection conn2 = cf.getFreeConnection();
       Connection conn3 = cf.getFreeConnection();
       Statement stmt = conn1.createStatement();
       ResultSet rs = stmt.executeQuery("select * from ADMINISTRATION");
       if (rs.next()) {
        System.out.println("conn1 y");
       } else {
        System.out.println("conn1 n");
       }
       stmt.close();
       conn1.close();
       Connection conn4 = cf.getFreeConnection();
       Connection conn5 = cf.getFreeConnection();

       stmt = conn5.createStatement();
       rs = stmt.executeQuery("select * from ADMINISTRATION");
       if (rs.next()) {
        System.out.println("conn5 y");
       } else {
        System.out.println("conn5 n");
       }

       conn2.close();
       conn3.close();
       conn4.close();
       conn5.close();
      } catch (Exception ex) {
       ex.printStackTrace();
      } finally {
       try {
        cf.close();
       } catch (Exception ex) {
        ex.printStackTrace();
       }
      }
     }

     /**
      * @param args
      */
     public static void main(String[] args) {
      String user = "ppuser";
      String password = "ppuser";
      String url = "jdbc:oracle:thin:@192.168.0.1:1521:PPDATA";
      String driver = "oracle.jdbc.driver.OracleDriver";
      ConnectionParam param = new ConnectionParam(driver, url, user, password);
      System.out.println("-------"+param.getDriver());
      ConnectionFactory cf = null;
      try {
       cf = new ConnectionFactory(param, new FactoryParam());
       Connection conn1 = null;
       long time = System.currentTimeMillis();
       for (int i = 0; i < 10; i++) {
        conn1 = cf.getFreeConnection();
        Statement stmt = conn1.createStatement();
        ResultSet rs = stmt.executeQuery("select * from actioncode");
        if (rs.next()) {
         System.out.println("conn1 y");
        } else {
         System.out.println("conn1 n");
        }
        conn1.close();
       }
       System.out.println("pool:" + (System.currentTimeMillis() - time));
       time = System.currentTimeMillis();
       Class.forName(param.getDriver()).newInstance();
       for (int i = 0; i < 10; i++) {
        conn1 = DriverManager.getConnection(param.getUrl(), param
          .getUser(), param.getPassword());
        Statement stmt = conn1.createStatement();
        ResultSet rs = stmt.executeQuery("select * from actioncode");
        if (rs.next()) {
         System.out.println("conn1 y");
         System.out.println(rs.getString(1));
         System.out.println(rs.getString(2));
        } else {
         System.out.println("conn1 n");
        }
        conn1.close();
       }
       System.out.println("no pool:" + (System.currentTimeMillis() - time));
      } catch (Exception e) {
       e.printStackTrace();
      } finally {
       try {
        cf.close();
       } catch (Exception e) {
        e.printStackTrace();
       }
      }
     }

    }

  • 相关阅读:
    javascript:void(0)是什么意思 天高地厚
    C#开发 WinForm中窗体显示和窗体传值相关知识
    c#在WinForm中重写ProgressBar控件(带%的显示)
    flash在C#中的应用
    c# winform 关于DataGridView的一些操作
    winform中输入数据的验证
    RadioButton和CheckBox
    Manifest文件的配置
    简单程序用于熟悉Activity生命周期
    Activity的生命周期
  • 原文地址:https://www.cnblogs.com/liaomin416100569/p/9331878.html
Copyright © 2011-2022 走看看