2013-10-17 48 views
0

我正在使用Struts 2開發一個java web應用程序。目前,在每個頁面加載時,我建立一個新的db連接,然後在請求結束時關閉這個db連接,就在渲染結果HTML之前。所以,每個請求都有自己的db連接。在Java中與靜態方法共享數據庫連接

我想在我的模型類中有一堆靜態方法,例如User.exists(id),如果給定的用戶ID存在,將返回true;如果沒有,則返回false。或其他實用方法,如User.getEmail(id)User.disable(id)

我的問題是,有沒有一種方便的方式與這些靜態方法共享數據庫連接?必須將連接作爲第二個參數傳遞給所有這些方法,例如User.exists(id, db)會很難看,並且不太方便。

如果我在每個這些實用程序方法中獲得新的數據庫連接,並在返回結果之前關閉它,那麼該怎麼辦?它會對性能產生什麼影響?有時候我可能需要在請求中調用這些方法20-30次(例如驗證用戶輸入時)。

+1

僅當您的數據庫連接完全線程安全時,這是不太可能的。使用連接池。 – SLaks

+0

@SLaks我正在使用一個由struts在每個頁面請求開始時調用的struts攔截器。數據庫連接在攔截器的'intercept()'方法中進行,並且在同一個方法中關閉,它知道請求已經完成了渲染。所以我認爲我在線程方面很安全。我關心的是在每個靜態工具方法中建立一個新的連接。這會影響性能嗎? –

+0

如果您正在使用JEE應用程序服務器,請使用它的連接池設施。然後你可以實現一個OSIV攔截器,如果使用Spring/hibernate只需要一個動作來建立一個事務會話。事務會話將只在攔截器解除展開時關閉,但如果不需要數據庫訪問,則不需要花費時間打開到數據庫的實際連接。 – Quaternion

回答

1

是的,這是可能的。對於你希望每個線程都有自己的連接的情況,你需要使用ThreadLocal,因爲每個請求都會產生它自己的線程。您只需確保在請求結束時關閉連接,即可使用Filter來實現。

過濾器應該位於任何其他過濾器之前,以確保連接在請求結束時關閉。

DBUtil:

public class DBUtil { 

    private static ThreadLocal<Connection> connectionHolder = new ThreadLocal<Connection>(); 

    public static Connection getConnection() { 
     Connection connection = connectionHolder.get(); 
     if (connection == null) { 
      //open the connection (lazy loaded) 

      //store it 
      connectionHolder.set(connection); 

     } 
     return connectionHolder.get(); 
    } 

    public static void close() { 
     Connection connection = connectionHolder.get(); 
     if (connection != null) { 
      //close the connection 

      //remove it from the connection holder 
      connectionHolder.remove(); 
     } 
    } 

} 

DBFilter

public void doFilter(ServletRequest request, ServletResponse response, 
      FilterChain chain) throws IOException, ServletException {  
    try { 
     chain.doFilter(request, response); 
    } finally { 
     DBUtil.close();   
    } 
} 

這是更好,如果你使用的這類事情的框架,例如Spring Framework通過進行代理你的服務,它已經做到這一點處理連接和交易也給你很多其他功能。

+0

有趣的,所以你說我可以有一個ThreadLocal數據庫連接,然後每次我調用'Db.getConnection()',它只會返回當前請求的唯一/本地數據庫連接?如果是這樣,你能給出一些關於如何實現它的細節,例如在過濾器中?然後我可以接受。 –

+0

@ClickUpvote完成。無論如何,我建議使用更完整的東西,比如Spring,它提供了這個和Transaction特性,所以你不需要自己製作。 –

+0

謝謝。你熟悉Struts嗎?Struts 2有一個'ActionContext',它似乎是線程安全的.. –