2013-08-07 72 views
0

我已經寫了一個Java函數,它運行MySQL查詢並返回結果。我在這裏使用這種方法實現了連接池:http://www.kodejava.org/how-do-i-create-a-database-connection-pool/。該函數正在工作,但連接時間仍然與沒有合併約190毫秒相同。有人可以告訴我我做錯了什麼嗎?Java MySQL連接池不工作

這是我的代碼:

public static ArrayList<Map<String,Object>> query(String q) throws Exception { 

    long start, end; 

    GenericObjectPool connectionPool = null; 

    String DRIVER = "com.mysql.jdbc.Driver"; 
    String URL = "jdbc:mysql://localhost/dbname"; 
    String USER = "root"; 
    String PASS = ""; 

    Class.forName(DRIVER).newInstance(); 

    connectionPool = new GenericObjectPool(); 
    connectionPool.setMaxActive(10); 

    ConnectionFactory cf = new DriverManagerConnectionFactory(URL, USER, PASS); 

    PoolableConnectionFactory pcf = new PoolableConnectionFactory(cf, connectionPool, null, null, false, true); 

    DataSource ds = new PoolingDataSource(connectionPool); 

    //create statement 
    Statement Stm = null; 

    try { 

     Connection Con = null; 
     PreparedStatement stmt = null; 

     start = System.currentTimeMillis(); 

     Con = ds.getConnection(); 

     end = System.currentTimeMillis(); 
     System.out.println("DB Connection: " + Long.toString(end - start) + " ms"); 

     //fetch out rows 
     ArrayList<Map<String, Object>> Rows = new ArrayList<Map<String,Object>>(); 

     Stm = Con.createStatement(); 

     //query 
     ResultSet Result = null; 

     boolean Returning_Rows = Stm.execute(q); 

     if (Returning_Rows) { 
      Result = Stm.getResultSet(); 
     } else { 
      return new ArrayList<Map<String,Object>>(); 
     } 

     //get metadata 
     ResultSetMetaData Meta = null; 
     Meta = Result.getMetaData(); 

     //get column names 
     int Col_Count = Meta.getColumnCount(); 
     ArrayList<String> Cols = new ArrayList<String>(); 
     for (int Index=1; Index<=Col_Count; Index++) { 
      Cols.add(Meta.getColumnName(Index)); 
     } 

     while (Result.next()) { 
      HashMap<String,Object> Row = new HashMap<String,Object>(); 
      for (String Col_Name:Cols) { 
       Object Val = Result.getObject(Col_Name); 
       Row.put(Col_Name,Val); 
      } 
      Rows.add(Row); 
     } 

     //close statement 
     Stm.close(); 


     //pass back rows 
     return Rows; 

    } catch (Exception Ex) { 

     System.out.print(Ex.getMessage()); 
     return new ArrayList<Map<String,Object>>(); 

    } finally { 

     if (Stm != null) { 
      Stm.close(); 
     } 
     if (Stm != null) { 
      Stm.close(); 
     } 

     System.out.println("Max connections: " + connectionPool.getMaxActive()); 
     System.out.println("Active connections: " + connectionPool.getNumActive()); 
     System.out.println("Idle connections: " + connectionPool.getNumIdle()); 

    } 

} 

這是控制檯輸出每次:

DB Connection: 186 ms 
Max connections: 10 
Active connections: 1 
Idle connections: 0 

更新:我應該注意,使用該工作原理是這樣的Java應用程序:執行,只運行一個查詢並關閉。我想如果PHP像這樣工作,並且默認使用連接池,那麼Java應該如何?如我錯了請糾正我。

+1

再一次,不需要爲運行一次應用程序創建連接池。如果您只是堅持一個連接的引用,那麼這是一個大小爲1的連接池。我認爲您對PHP頁面的性能與您自己的Java應用程序之間的200ms差異感到癡迷。 – ktm5124

+0

問題是,它是高度使用的應用程序,我說它每次在大系統上加載任何頁面時都會運行...每天數十萬次。我想刮掉完全浪費的200毫秒。 – Caballero

+0

可能重複[PHP vs Java MySQL連接池](http://stackoverflow.com/questions/18105989/php-vs-java-mysql-connection-pooling) – RandomSeed

回答

2

您創建了一個連接池,但不會放入任何東西。連接池在創建時爲空,因此您的第一個請求將保證創建一個新的連接,並且與手動獲取連接一樣慢。

嘗試將您的代碼放入一個循環中,您可以在其中反覆從池中獲取連接。嘗試一次,五次,十次和十五次。注意結果如何變化。

一些連接池支持自動創建並保持一個最低號準備使用的連接,以及一個最大。池初始化時,它將預取連接,所以前幾個呼叫不會延遲。

+0

問題是,該應用程序只運行一個查詢,我'我在「更新」中解釋過更多。 – Caballero

0

您不會看到與數據庫的單個請求的區別。你必須用多個(併發)請求來測試這個。

而且順便說一下:你遵循Java命名約定,並以小寫字母開始所有對象。

0

您可以通過致電connectionPool.addObject()預裝您的游泳池。在開始時它是空的,並且只有在發佈查詢後才創建連接。

0

您的用例不保證連接池。它只需要一個連接。 您正在使用的游泳池類GenericObjectPool有一個方法addObject();。這將創建對象並將其添加到池中。這將避免以後創建連接。