簡體   English   中英

我應該如何使用Java Servlet,JSP和Tomcat管理連接到數據庫

[英]How should I manage connecting to a database using java servlets, JSP & Tomcat

對於Servlet和JSP以及使用數據庫,我還很陌生。

目前,我的Web應用程序的“模型”部分中有一個類,該類包含許多我編寫的用於執行數據庫查詢和更新的方法。 目前,在每種方法中,我都在創建數據庫連接,執行SQL任務,然后關閉連接。

當我只是為自己制作小型應用程序時,這種方法效果很好,但我開始意識到,如果很多人同時使用我的應用程序,那么顯然會發現創建數據庫連接並為每個方法調用關閉它們都是一個麻煩。時間昂貴的過程。 所以我需要改變做事的方式。

在Basham,Sierra和Bates的Head First Servlet&JSP中,他們描述了如何使用ServletContextListener實現在Web應用程序的部署上創建一個對象,該對象將作為ServletContext的屬性添加。 作者沒有涉及它,而是暗示人們經常將數據庫連接添加為ServletContext的屬性。 我以為自己想實現此目的,但是在閱讀了有關數據庫連接管理的stackoverflow文章后,我不太確定。

但是,由於我只是從servlet和JSP入手,更不用說J2EE的其余部分了,所以很多文章超出了我的范圍。

那篇文章對我來說很重要:

  • 某些事情可能會中斷該數據庫連接,如果我們僅依賴該連接,則需要重新部署應用程序以重新啟動連接。 這個對嗎?

  • 我們應該在容器上回復以為我們管理數據庫連接。 很好,但是如何實現? 如何與容器通信? (請記住,我剛剛開始使用Servlet和JSP)。

  • 一般而言,就Servlet設計而言,每個請求類型都有一個servlet類,並且通常只有一種對數據庫的調用,即特定的更新或查詢。 對於我來說,將這些方法放在各自的servlet中是否是一種更好的設計,而不是為我提供一個具有查詢數據庫的所有方法的類,還是會違反Model-View-Controller模式?

我無法想象太多用戶會遇到太多問題,這會降低用戶體驗:),但我想盡可能地開始做正確的事情。

提前非常感謝您的評論

Tomcat網站的下一頁詳細介紹了如何連接Tomcat和mySQL。 您不想自己動手,已經有太多可用的DataSource池在生產環境中進行了調試和嘗試。

使用池的主要問題是,當您調用close時,連接不會終止,而是只會返回到池中。 因此,確保您在try / finally塊中關閉資源很重要。 在這里尋找示例

我將檢查連接池,特別是C3P0Apache Commons DBCP之類的框架。

這兩個軟件包都將為您維護和管理數據庫連接的集合。

通常,連接是預先建立的,並根據需要將其移交給請求線程。 可以在分發連接之前對連接進行驗證(如果連接斷開,則可以在客戶端使用連接之前進行重建)。

進入Web應用程序的方法是讓連接池管理您的連接。 這將允許您的執行線程共享數據庫連接,這很重要,因為連接數據庫通常是一項昂貴的操作。 使用連接池通常只是配置任務,因為大多數容器都支持管理連接池。

從您的代碼的角度來看,幾乎沒有更改。 基本上:

  • 連接池通過DataSource接口訪問,而非池化連接可以通過舊的DriverManager訪問。
  • 要獲取DataSource ,通常必須使用JNDI,因為這是在J2EE應用程序中發布連接池的標准方法。
  • 您想要盡快close() Connection對象。 這將使連接返回到無需與數據庫斷開連接的池,以便其他線程可以使用它。

與往常一樣,您應該在每個JDBC資源(連接,語句,結果集)上調用close() )以避免泄漏。 這在服務器應用程序中特別重要,因為它們很少重啟,因此泄漏會隨着時間的推移而累積,最終會使您的應用程序出現故障。

這是來自http://download.oracle.com/javase/1.4.2/docs/guide/jdbc/getstart/datasource.html的一些示例代碼(注意: 不是異常安全的 )。 如您所見,一旦獲得Connection參考,就沒有什么特別的了。

Context ctx = new InitialContext();
DataSource ds = (DataSource)ctx.lookup("jdbc/AcmeDB");
Connection con = ds.getConnection("genius", "abracadabra");
con.setAutoCommit(false);
PreparedStatement pstmt = con.prepareStatement(
                            "SELECT NAME, TITLE FROM PERSONNEL WHERE DEPT = ?");
pstmt.setString(1, "SALES");
ResultSet rs = pstmt.executeQuery();

System.out.println("Sales Department:");
while (rs.next()) {
        String name = rs.getString("NAME");
        String title = rs.getString("TITLE");
        System.out.println(name + "  ; ;" + title);
}
pstmt.setString(1, "CUST_SERVICE");
ResultSet rs = pstmt.executeQuery();

System.out.println("Customer Service Department:");
while (rs.next()) {
        String name = rs.getString("NAME");
        String title = rs.getString("TITLE");
        System.out.println(name + "  ; ;" + title);
}
rs.close();
pstmt.close();
con.close();

作者沒有涉及它,而是暗示人們經常將數據庫連接添加為ServletContext的屬性。

那不是處理此問題的標准方法。 傳統方法是使用連接池,准備使用的連接池 然后,應用程序從連接借用連接,並在完成后將它們返回到池中。

您可以將多種獨立的連接池實現(C3P0,Commons DBCP,Bone CP)捆綁在應用程序中。 但是,當使用Servlet或Java EE容器時,我將使用容器提供的連接池。 然后,通過JNDI從應用程序獲取一個DataSource (連接池上的句柄),以從中獲取JDBC連接(並關閉它以將其返回到池中)。

配置池的方法顯然是特定於容器的,因此您需要參考容器的文檔。 好消息是,Tomcat提供了幾個示例這些示例顯示了如何執行此操作,如何通過JNDI獲取數據源以及如何編寫適當的JDBC代碼(請閱讀本頁底部)。

參考

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM