我应该如何使用Javaservlet、JSP和;雄猫

我应该如何使用Javaservlet、JSP和;雄猫,java,mysql,database-connection,Java,Mysql,Database Connection,我对servlet和JSP以及数据库的使用还很陌生 目前,我在我的web应用程序的“模型”部分有一个类,它有许多我编写的用于执行数据库查询和更新的方法。目前,在每种方法中,我都在创建数据库连接,执行SQL操作,然后关闭连接 这在我为自己制作小型应用程序时效果很好,但我开始意识到,如果很多人同时使用我的应用程序,那么创建数据库连接并关闭每个方法调用的数据库连接显然是一个耗时的过程。所以我需要改变我做事的方式 在Basham、Sierra和Bates的Head First Servlet&JSP中,

我对servlet和JSP以及数据库的使用还很陌生

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

这在我为自己制作小型应用程序时效果很好,但我开始意识到,如果很多人同时使用我的应用程序,那么创建数据库连接并关闭每个方法调用的数据库连接显然是一个耗时的过程。所以我需要改变我做事的方式

在Basham、Sierra和Bates的Head First Servlet&JSP中,他们描述了如何使用ServletContextListener实现在web应用程序的部署上创建一个对象,该对象将作为ServletContext的属性添加。作者没有深入讨论它,但暗示人们通常将数据库连接添加为ServletContext的属性。我想我会为自己实现这一点,但读完后我不太确定

然而,由于我刚刚开始使用servlet和JSP,更不用说J2EE的其余部分了,这篇文章中的很多内容我都看不懂

那篇文章对我来说最突出的几点是:

  • 数据库连接可能会中断,如果我们只依赖于该连接,那么我们需要重新部署应用程序以重新启动连接。这是正确的吗

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

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

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

非常感谢您的评论


Joe

我会检查连接池,特别是像or这样的框架

这两个包都将为您维护和管理数据库连接集合

通常,连接是预先建立的,并根据请求线程的需要分发给它们。连接可以在分发之前进行验证(如果连接中断,可以在客户端使用连接之前重新创建)。

详细介绍了如何连接Tomcat和mySQL。您不想使用自己的数据源池,因为已经有太多的数据源池可用,并且已经在生产环境中进行了调试和尝试


使用池的主要问题是,调用close时连接不会终止,而是返回到池中。因此,务必确保在try/finally块中关闭资源

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

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

  • 连接池可通过
    DataSource
    接口访问,而非池连接可通过旧的
    DriverManager
    访问
  • 要获取
    数据源
    ,通常必须使用JNDI,因为这是在J2EE应用程序中发布连接池的标准方法
  • 您希望尽快关闭对象。这将返回到池WO的连接,而无需断开与DB的连接,以便其他线程可以使用它
和往常一样,应该对每个JDBC资源(连接、语句、结果集)调用
close()
,以避免泄漏。这在服务器应用程序中特别重要,因为它们很少重新启动,因此泄漏会随着时间的推移而累积,最终会导致应用程序出现故障

这是来自的一些示例代码(注意:非异常安全的)。正如您所看到的,一旦获得
连接
引用,就没有什么特别的了

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(); Context ctx=新的InitialContext(); DataSource ds=(DataSource)ctx.lookup(“jdbc/AcmeDB”); 连接con=ds.getConnection(“genius”、“abracadabra”); con.setAutoCommit(假); 准备好的报表pstmt=con.prepareStatement( “从人员中选择姓名、职务,其中DEPT=?”; pstmt.setString(1,“销售”); 结果集rs=pstmt.executeQuery(); System.out.println(“销售部门:”); while(rs.next()){ 字符串名称=rs.getString(“名称”); 字符串标题=rs.getString(“标题”); System.out.println(name+“;;”+title); } pstmt设置字符串(1,“客户服务”); 结果集rs=pstmt.executeQuery(); System.out.println(“客户服务部”); while(rs.next()){ 字符串名称=rs.getString(“名称”); 字符串标题=rs.getString(“标题”); System.out.println(name+“;;”+title); } rs.close(); pstmt.close(); con.close(); 作者没有深入讨论它,但暗示人们通常将数据库连接添加为ServletContext的属性

这不是处理这个问题的标准方法。特拉迪酒店