【问题标题】:How should I manage connecting to a database using java servlets, JSP & Tomcat我应该如何管理使用 java servlet、JSP 和 Tomcat 连接到数据库
【发布时间】:2010-09-11 14:52:18
【问题描述】:

我对 Servlet 和 JSP 以及使用数据库非常陌生。

目前,我的网络应用程序的“模型”部分中有一个类,其中包含我编写的许多方法来执行数据库查询和更新。目前,在每种方法中,我都在创建数据库连接,执行 SQL 操作,然后关闭连接。

当我只是为自己制作小应用程序时,这很好用,但我开始意识到,如果很多人同时使用我的应用程序,那么创建数据库连接并为每种方法关闭它们就会变得很明显通话是一个耗时的过程。所以我需要改变我做事的方式。

在 Basham、Sierra 和 Bates 的 Head First Servlet 和 JSP 中,他们描述了如何使用 ServletContextListener 实现在 Web 应用程序的部署上创建一个对象,该对象将作为 ServletContext 的属性添加。作者没有深入探讨,但暗示人们经常将数据库连接添加为 ServletContext 的属性。我以为我想为自己实现这个,但在阅读this stackoverflow article on database connection management 之后我不太确定。

但是,由于我只是从 servlet 和 JSP 开始,更不用说 J2EE 的其余部分了,那篇文章的很多内容都超出了我的理解范围。

那篇文章让我印象深刻的观点是:

  • 可能会发生破坏该数据库连接的事情,如果我们仅依赖该连接,那么我们需要重新部署我们的应用程序以重新启动连接。这是正确的吗?

  • 我们应该回复容器来为我们管理数据库连接。很好,但是这是如何实现的?如何与容器通信? (请记住,我刚刚开始使用 Servlet 和 JSP)。

  • 就一般的 Servlet 设计而言,每个请求类型都有一个 servlet 类,并且通常只有一种类型的数据库调用,即特定的更新或查询。与其拥有一个包含所有查询数据库方法的类,不如将这些方法放在各自的 servlet 中,还是违反模型-视图-控制器模式?

我无法想象我会遇到太多问题,因为太多的用户会减慢用户体验 :) 但如果可能的话,我想开始做正确的事情。

非常感谢您的 cmets

【问题讨论】:

    标签: java mysql database-connection


    【解决方案1】:

    The following page on Tomcat's website详细介绍了Tomcat和mySQL的连接方法。您不想自己动手,已经有太多可用的 DataSource 池已经在生产环境中调试和尝试过了。

    使用池的主要一点是,当您调用 close 时连接不会终止,而是直接返回到池中。因此,确保在 try/finally 块中关闭资源很重要。 Look here for a sample.

    【讨论】:

    • 感谢您的回答。很有帮助。
    【解决方案2】:

    我会检查连接池,特别是像 C3P0Apache Commons DBCP 这样的框架。

    这两个软件包都会为您维护和管理数据库连接集合。

    通常会提前建立连接,并在需要时分发给请求线程。可以在分发之前验证连接(如果连接断开,则可以在客户端使用它们之前重新建立连接)。

    【讨论】:

    • 感谢您的回答。这很有帮助。
    【解决方案3】:

    进入网络应用程序的方法是让连接池管理您的连接。这将允许您的执行线程共享数据库连接,这一点很重要,因为连接到数据库通常是一项昂贵的操作。使用连接池通常只是一项配置任务,因为大多数容器都支持管理连接池。

    从您的代码的角度来看,更改很少。基本上:

    • 连接池通过DataSource接口访问,而非池连接可以通过旧的DriverManager访问。
    • 要获得DataSource,您通常必须使用 JNDI,因为这是在 J2EE 应用程序中发布连接池的标准方法。
    • 你想尽快close()Connection对象。这将返回到池的连接,而不会断开与数据库的连接,以便其他线程可以使用它。

    与往常一样,您应该在每个 JDBC 资源(连接、语句、结果集)上调用 close() 以避免泄漏。这在服务器应用程序中尤为重要,因为它们很少重新启动,因此泄漏会随着时间的推移而累积,最终会使您的应用程序出现故障。

    这是来自http://download.oracle.com/javase/1.4.2/docs/guide/jdbc/getstart/datasource.html 的一些示例代码(注意:不是异常安全的)。如您所见,一旦您获得 Connection 引用,就没有什么特别之处了。

    上下文 ctx = new InitialContext(); 数据源 ds = (DataSource)ctx.lookup("jdbc/AcmeDB"); Connection con = ds.getConnection("genius", "abracadabra"); con.setAutoCommit(false); PreparedStatement pstmt = con.prepareStatement( “从部门人员那里选择姓名,职务=?”); pstmt.setString(1, "销售"); 结果集 rs = pstmt.executeQuery(); System.out.println("销售部:"); 而(rs.next()){ 字符串名称 = rs.getString("NAME"); 字符串标题 = rs.getString("TITLE"); System.out.println(name + " ; ;" + title); } pstmt.setString(1, "CUST_SERVICE"); 结果集 rs = pstmt.executeQuery(); System.out.println("客服部:"); 而(rs.next()){ 字符串名称 = rs.getString("NAME"); 字符串标题 = rs.getString("TITLE"); System.out.println(name + " ; ;" + title); } rs.close(); pstmt.close(); con.close();

    【讨论】:

      【解决方案4】:

      作者没有深入探讨,但暗示人们经常将数据库连接添加为 ServletContext 的属性。

      这不是处理此问题的标准方法。传统方法是使用连接池,即准备使用的连接池。然后,应用程序从池中借用连接,并在完成后将它们返回到池中。

      您可以将多个独立的连接池实现(C3P0、Commons DBCP、Bone CP)捆绑到您的应用程序中。但是当使用 Servlet 或 Java EE 容器时,我会使用容器提供的连接池。然后,通过 JNDI 从应用程序中获取DataSource(连接池的句柄)以从中获取 JDBC 连接(并关闭它以将其返回到池中)。

      配置池的方式显然是特定于容器的,因此您需要参考容器的文档。好消息是 Tomcat 提供了several examples 展示了如何做到这一点,如何通过 JNDI 获取数据源以及如何编写正确的 JDBC 代码(阅读到页面底部)。

      参考文献

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-09-28
        • 2012-01-06
        • 1970-01-01
        • 2011-03-30
        • 1970-01-01
        • 2012-09-12
        相关资源
        最近更新 更多