天天看點

Java Web簡明教程–Java篇[11]–資料庫連接配接池

前面(Java篇[9])示範了兩個極端的資料庫使用方式:

第一種:每次使用資料庫,都建立一個新的連接配接,使用完畢後關閉連接配接。這種是非常安全的,因為每次使用的都是新連接配接互不幹扯。缺點是非常浪費時間和資源,要知道建立連接配接是比較浪費時間的。

第二種,就一個資料庫連接配接,該連接配接儲存在一個靜态的對象裡面,不管多少次請求都用這個連接配接來實作。優點是速度快,缺點是不可靠,這個缺點對Web網站來說是緻命的。據貓哥了解,不同的資料庫驅動對資料庫連接配接的處理方式是不确定的,比如MySQL如果隻采用一個資料庫連接配接,那麼可能會出現:a此連接配接長時間不用被收回;b多個同時并發的通路使用此連接配接,因為MySQL連接配接是串行執行資料庫操作的,是以需要長時間排隊。

OK,說白了,第一種就是每次都用新筷子,用完就扔了買新的。第二種就是一共就一雙筷子,如果人多就排隊使用。

那麼資料庫連接配接池是一種什麼樣的思想呢,其實很簡單,就是如果我們常用20雙筷子(最大并發量20,最多20人同時通路),我們就設定個20容量的池子。來一個通路就配置設定一個連接配接,直到20個都配置設定完了那就報錯。

就這麼簡單,貓哥簡單實作如下(就按20個最大連接配接實作):

import java.sql.*;
import java.util.LinkedList;
public class MysqlPool {
    //這就是我們的池子,想下為啥用static,為啥用LinkedList
    private static LinkedList pool = new LinkedList(); 
    //池水的深度(哈哈,其實就是最大連接配接數)
    private static int maxCount=20;
    public static void init(){//初始化,就是讓20個連接配接有意義
        try{
      for(int i=0;i
        MysqlHandler handler=new MysqlHandler();
                Connection connection = handler.buildConnection();//建立連接配接,并放于池中,不用擔心這個連接配接找不到了,因為已經是池中之物了
                pool.add(connection);
            }
         }catch(Exception e){//此處threw exception更好,為何?
          e.printStackTrace();
         }
    }
 
    public static Connection getConnecton(){//從池中擷取一個連接配接
        if(pool.size()==0)//配置設定完了
        {
      return null;//沒有連接配接可用
        }
        else{
      return pool.remove(0);//删除第一個對象并傳回
        }
    }
 
    public static void release(Connection connection){//使用完的歸還給池子
        pool.add(connection);
    }
   
}      
import java.sql.*;
public class TestMysql {//測試MysqlHandler類
    public static void main(String[] args)  {
  try {//捕獲異常
    long start=System.currentTimeMillis();//産生一個目前的毫秒(自1970年1月1日0時起的毫秒數)
    MysqlPool.init();
    for(int i=0;i<1000;i++){
    testOneTime();
    }
    long end=System.currentTimeMillis();
    System.out.println("\n消耗時間:"+(end-start)+"毫秒");
  } catch (SQLException e) {
    e.printStackTrace();
  }
    }
    //測試一次完整查詢
    private static void testOneTime()throws SQLException{//可能會有異常,我們在更廣闊的天地捕獲之
  Connection conn = MysqlPool.getConnecton();
  Statement stmt = conn.createStatement();
  ResultSet rs = null;
  rs=stmt.executeQuery("select * from student_info");
  rs.close();
  stmt.close();
 
  MysqlPool.release(conn);//注意Statement和ResultSet是需要釋放的,而Connection放在池子裡面循環使用,不必釋放,為啥呢?因為Connection建立連接配接太耗時!
    }
}      

OK,上面貓哥實作了一個相當簡單的池子,但是也夠用了,主要是體會池子的思想,還是相當貼近現實啊。