`
abei1
  • 浏览: 20664 次
最近访客 更多访客>>
社区版块
存档分类
最新评论

[转帖]java数据库链接池

阅读更多

       首先说明一下,这个数据库链接池不是我写的。是我在网上找到的,由于代码并不全,因此进行了一些填充。可以正常运行了。所以贴出来希望能帮到需要的人。

       这个数据库链接池的好处在于当用户从数据库链接池中的到连接后,并不需要特殊的方法将链接关闭,直接用close方法就可以关闭了。废话少说,上代码!!!!

      再次说明一下,以下的代码是根据网上得到的部分代码填充得到的,并不代表没有错误。如果那位高手能将代码完善感激不尽。

     下面的一段代码是一些数据库的属性。

java 代码
  1. public class ConnectionParam {   
  2.   
  3.     private String driver = null;                                //数据库驱动程序   
  4.     private String host = null;                                        //数据连接的URL   
  5.     private String user = null;                                        //数据库用户名   
  6.     private String password = null;                                //数据库密码   
  7.     private String dataBase= null;   
  8.     private String url = null;   
  9.     private int minConnection = 0;                //初始化连接数   
  10.     private int maxConnection = 0;                //最大连接数   
  11.     private long timeoutValue = 0;            //连接的最大空闲时间   
  12.     private long waitTime = 0;                //取连接的时候如果没有可用连接最大的等待时间   
  13.        
  14.     public ConnectionParam(){   
  15.         super();   
  16.         try {   
  17.             String tmp = null;   
  18.             int value = 0;   
  19.                                            //CommonUtil.getPropertie("");方法是自己写的一个从属性文件中读取信息的方法。   
  20.             this.driver = CommonUtil.getPropertie("driver");      
  21.             this.host = CommonUtil.getPropertie("host");                                       
  22.             this.user = CommonUtil.getPropertie("user");                                        
  23.             this.password = CommonUtil.getPropertie("password");                               
  24.             this.dataBase= CommonUtil.getPropertie("dataBase");   
  25.             this.url =CommonUtil.getPropertie("url");   
  26.                
  27.             tmp = CommonUtil.getPropertie("maxConnection");   
  28.             value = 0;   
  29.             if(CommonUtil.isNull(tmp)){   
  30.                 value = 0;   
  31.             }else{   
  32.                 value = Integer.parseInt(tmp);   
  33.             }   
  34.             this.maxConnection = value;                  
  35.                
  36.             tmp = CommonUtil.getPropertie("timeoutValue");   
  37.             value = 0;   
  38.             if(CommonUtil.isNull(tmp)){   
  39.                 value = 0;   
  40.             }else{   
  41.                 value = Integer.parseInt(tmp);   
  42.             }   
  43.             this.timeoutValue = value;               
  44.                
  45.                
  46.             tmp = CommonUtil.getPropertie("waitTime");   
  47.             value = 0;   
  48.             if(CommonUtil.isNull(tmp)){   
  49.                 value = 0;   
  50.             }else{   
  51.                 value = Integer.parseInt(tmp);   
  52.             }   
  53.             this.waitTime = value;          
  54.         } catch (IOException e) {   
  55.             // TODO Auto-generated catch block   
  56.             e.printStackTrace();   
  57.         }                                   
  58.                      
  59.            
  60.     }   
  61. }  

    下面这段代码是实现连接池的,其中的一些方法并没有实现。请各位见谅。

java 代码
  1. import java.io.PrintWriter;   
  2. import java.sql.Connection;   
  3. import java.sql.DriverManager;   
  4. import java.sql.SQLException;   
  5. import java.util.ArrayList;   
  6. import java.util.Iterator;   
  7. import java.util.List;   
  8.   
  9. import javax.sql.DataSource;   
  10.   
  11.   
  12. public class DataSourceImpl implements DataSource {   
  13.        
  14.     private ConnectionParam connParam = null;   
  15.     private List conns = null;   
  16.        
  17.     public DataSourceImpl(ConnectionParam param){   
  18.         conns = new ArrayList();   
  19.         this.connParam = param;   
  20.     }   
  21.   
  22.     public Connection getConnection() throws SQLException {   
  23.          //首先从连接池中找出空闲的对象   
  24.         Connection conn = getFreeConnection(0);   
  25.         Connection conn2 = null;   
  26.         if(conn == null){   
  27.                 //判断是否超过最大连接数,如果超过最大连接数   
  28.                 //则等待一定时间查看是否有空闲连接,否则抛出异常告诉用户无可用连接   
  29.                 if(getConnectionCount() >= connParam.getMaxConnection())   
  30.                         conn = getFreeConnection(connParam.getWaitTime());   
  31.                 else{//没有超过连接数,重新获取一个数据库的连接   
  32.                     try {   
  33.                         Class.forName(connParam.getDriver()).newInstance();   
  34.                         conn2 = DriverManager.getConnection(connParam.getUrl(),    
  35.                                 connParam.getUser(), connParam.getPassword());   
  36.                     } catch (InstantiationException e) {   
  37.                         e.printStackTrace();   
  38.                     } catch (IllegalAccessException e) {   
  39.                         e.printStackTrace();   
  40.                     } catch (ClassNotFoundException e) {   
  41.                         e.printStackTrace();   
  42.                     }   
  43.                         //代理将要返回的连接对象   
  44.                         _Connection _conn = new _Connection(conn2,true);   
  45.                         synchronized(conns){   
  46.                                 conns.add(_conn);   
  47.                         }   
  48.                         conn = _conn.getConnection();   
  49.                 }   
  50.         }   
  51.         return conn;   
  52.     }   
  53.   
  54.     public Connection getConnection(String username, String password)   
  55.             throws SQLException {   
  56.          //首先从连接池中找出空闲的对象   
  57.         Connection conn = getFreeConnection(0);   
  58.         Connection conn2 = null;   
  59.         if(conn == null){   
  60.                 //判断是否超过最大连接数,如果超过最大连接数   
  61.                 //则等待一定时间查看是否有空闲连接,否则抛出异常告诉用户无可用连接   
  62.                 if(getConnectionCount() >= connParam.getMaxConnection())   
  63.                         conn = getFreeConnection(connParam.getWaitTime());   
  64.                 else{//没有超过连接数,重新获取一个数据库的连接   
  65.                         connParam.setUser(username);   
  66.                         connParam.setPassword(password);   
  67.                         try {   
  68.                             Class.forName(connParam.getDriver()).newInstance();   
  69.                             conn2 = DriverManager.getConnection(connParam.getUrl(),    
  70.                                     username, password);   
  71.                         } catch (InstantiationException e) {   
  72.                             // TODO Auto-generated catch block   
  73.                             e.printStackTrace();   
  74.                         } catch (IllegalAccessException e) {   
  75.                             // TODO Auto-generated catch block   
  76.                             e.printStackTrace();   
  77.                         } catch (ClassNotFoundException e) {   
  78.                             // TODO Auto-generated catch block   
  79.                             e.printStackTrace();   
  80.                         }   
  81.                            
  82.                         //代理将要返回的连接对象   
  83.                         _Connection _conn = new _Connection(conn2,true);   
  84.                         synchronized(conns){   
  85.                                 conns.add(_conn);   
  86.                         }   
  87.                         conn = _conn.getConnection();   
  88.                 }   
  89.         }   
  90.         return conn;   
  91.     }   
  92.   
  93.     public PrintWriter getLogWriter() throws SQLException {   
  94.         // TODO Auto-generated method stub   
  95.         return null;   
  96.     }   
  97.   
  98.     public int getLoginTimeout() throws SQLException {   
  99.         // TODO Auto-generated method stub   
  100.         return 0;   
  101.     }   
  102.   
  103.     public void setLogWriter(PrintWriter out) throws SQLException {   
  104.         // TODO Auto-generated method stub   
  105.   
  106.     }   
  107.   
  108.     public void setLoginTimeout(int seconds) throws SQLException {   
  109.         // TODO Auto-generated method stub   
  110.   
  111.     }   
  112.        
  113.     public void initConnection(){   
  114. //       TODO Auto-generated method stub   
  115.     }   
  116.        
  117.     public void stop(){   
  118. //       TODO Auto-generated method stub   
  119.     }   
  120.        
  121.   
  122.        
  123.        
  124.     /**  
  125.      * 从连接池中取一个空闲的连接  
  126.      * @param nTimeout        如果该参数值为0则没有连接时只是返回一个null  
  127.      * 否则的话等待nTimeout毫秒看是否还有空闲连接,如果没有抛出异常  
  128.      * @return Connection  
  129.      * @throws SQLException  
  130.      */  
  131.     protected synchronized Connection getFreeConnection(long nTimeout)    
  132.             throws SQLException   
  133.     {   
  134.             Connection conn = null;   
  135.             Iterator iter = conns.iterator();   
  136.             while(iter.hasNext()){   
  137.                     _Connection _conn = (_Connection)iter.next();   
  138.                     if(!_conn.isInUse()){   
  139.                             conn = _conn.getConnection();   
  140.                             _conn.setInUse(true);                                   
  141.                             break;   
  142.                     }   
  143.             }   
  144.             if(conn == null && nTimeout > 0){   
  145.                     //等待nTimeout毫秒以便看是否有空闲连接   
  146.                     try{   
  147.                             Thread.sleep(nTimeout);   
  148.                     }catch(Exception e){}   
  149.                     conn = getFreeConnection(0);   
  150.                     if(conn == null)   
  151.                             throw new SQLException("没有可用的数据库连接");   
  152.             }   
  153.             return conn;   
  154.     }   
  155.        
  156.     /**  
  157.      * 关闭该连接池中的所有数据库连接  
  158.      * @return int 返回被关闭连接的个数  
  159.      * @throws SQLException  
  160.      */  
  161.     public int close() throws SQLException   
  162.     {   
  163.             int cc = 0;   
  164.             SQLException excp = null;   
  165.             Iterator iter = conns.iterator();   
  166.             while(iter.hasNext()){   
  167.                     try{   
  168.                             ((_Connection)iter.next()).close();   
  169.                             cc ++;   
  170.                     }catch(Exception e){   
  171.                             if(e instanceof SQLException)   
  172.                                     excp = (SQLException)e;   
  173.                     }   
  174.             }   
  175.             if(excp != null)   
  176.                     throw excp;   
  177.             return cc;   
  178.     }   
  179.        
  180.     /**  
  181.      * 返回当前链接的个数  
  182.      * @return  
  183.      */  
  184.     private int getConnectionCount(){   
  185.            
  186.         Iterator iter = conns.iterator();   
  187.         int count = 0;   
  188.          while(iter.hasNext()){   
  189.                  _Connection _conn = (_Connection)iter.next();   
  190.                  if(_conn.isInUse()){   
  191.                    count++;   
  192.                  }   
  193.          }   
  194.         return count;   
  195.     }   
  196.   
  197.   
  198.   
  199. }  

下面的是一个代理类。用来实现直接用close关闭连接。

java 代码
  1. import java.lang.reflect.InvocationHandler;   
  2. import java.lang.reflect.Method;   
  3. import java.lang.reflect.Proxy;   
  4. import java.sql.Connection;   
  5. import java.sql.SQLException;   
  6.   
  7.   
  8. public class _Connection implements InvocationHandler {   
  9.   
  10.      private final static String CLOSE_METHOD_NAME = "close";   
  11.      private Connection conn = null;   
  12.      //数据库的忙状态   
  13.      private boolean inUse = false;   
  14.      //用户最后一次访问该连接方法的时间   
  15.      private long lastAccessTime = System.currentTimeMillis();   
  16.         
  17.      _Connection(Connection conn, boolean inUse){   
  18.              this.conn = conn;   
  19.              this.inUse = inUse;   
  20.      }   
  21.      /**  
  22.       * Returns the conn.  
  23.       * @return Connection  
  24.       */  
  25.      public Connection getConnection() {   
  26.              //返回数据库连接conn的接管类,以便截住close方法   
  27.              Connection conn2 = (Connection)Proxy.newProxyInstance(   
  28.                      conn.getClass().getClassLoader(),   
  29.                      conn.getClass().getInterfaces(),this);   
  30.              return conn2;   
  31.      }   
  32.      /**  
  33.       * 该方法真正的关闭了数据库的连接  
  34.       * @throws SQLException  
  35.       */  
  36.      void close() throws SQLException{   
  37.              //由于类属性conn是没有被接管的连接,因此一旦调用close方法后就直接关闭连接   
  38.              conn.close();   
  39.      }   
  40.      /**  
  41.       * Returns the inUse.  
  42.       * @return boolean  
  43.       */  
  44.      public boolean isInUse() {   
  45.              return inUse;   
  46.      }   
  47.   
  48.      /**  
  49.       * @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object)  
  50.       */  
  51.      public Object invoke(Object proxy, Method m, Object[] args)    
  52.              throws Throwable    
  53.      {   
  54.              Object obj = null;   
  55.              //判断是否调用了close的方法,如果调用close方法则把连接置为无用状态   
  56.              if(CLOSE_METHOD_NAME.equals(m.getName()))   
  57.                      setInUse(false);                   
  58.              else  
  59.                      obj = m.invoke(conn, args);           
  60.              //设置最后一次访问时间,以便及时清除超时的连接   
  61.              lastAccessTime = System.currentTimeMillis();   
  62.              return obj;   
  63.      }   
  64.                 
  65.      /**  
  66.       * Returns the lastAccessTime.  
  67.       * @return long  
  68.       */  
  69.      public long getLastAccessTime() {   
  70.              return lastAccessTime;   
  71.      }   
  72.   
  73.      /**  
  74.       * Sets the inUse.  
  75.       * @param inUse The inUse to set  
  76.       */  
  77.      public void setInUse(boolean inUse) {   
  78.    &
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics