【问题标题】:A lot of database connections jsp很多数据库连接jsp
【发布时间】:2014-03-23 01:01:31
【问题描述】:

我用 Spring 和 Hibernate 制作了一个 Java Webapp,我必须从数据库中获取大量数据,但是我遇到了一个问题,因为应用程序太慢了,我需要让它更快。我认为更高的问题是我在每个jsp文件中执行的conexions数量,我不知道如何解决它。我认为这些连接都是必需的,但也许我可以修改部分代码以使其更快。我通过模型中的 Hibernate 和 Spring 将数据传递给 jsp,但是在 jsp 中我必须与数据库建立连接以获取更多信息,这些信息在另一个类中。比如我有一些球员,在球员中我有他们球队的ID,所以我必须在jsp中连接取球队的名字,因为我只知道ID。我将向您展示我如何将应用程序与数据库连接起来:

try {
    Class.forName("org.gjt.mm.mysql.Driver");
    Connection conexion = DriverManager.getConnection("jdbc:mysql://localhost:3306/database", "user", "pwd");
    if (!conexion.isClosed()) {
        // La consulta
        Statement st = conexion.createStatement();
        ResultSet rs = st.executeQuery("SELECT * FROM entity");

        while (rs.next()){
            aaa = rs.getObject("aaa").toString();
        }

        // cierre de la conexion
        conexion.close();
    }
    else 
        // Error en la conexion
        out.println("fallo");
}
catch (Exception e) {
    // Error en algun momento.
    out.println("Excepcion "+e);
    e.printStackTrace();
}

我在同一个 jsp 中多次这样做,在更大的 jsp 中甚至 10-15 次。 我可以在jsp开头打开conexion,最后关闭conexion,将所有jsp代码和html放在conexion中,与数据库只建立1个连接吗?

还有一个疑问,在同一个连接中,如果我必须做 2 个查询,我会这样做:

        Statement st = conexion.createStatement();
        ResultSet rs = st.executeQuery("SELECT * FROM entity");

        while (rs.next()){
            aaa = rs.getObject("aaa").toString();
        }

        st = conexion.createStatement();
        rs = st.executeQuery("select * from entity2");

        while (rs.next()){
            bbb = rs.getObject("bbb").toString();
        }

那么,我为查询创建了一个新的语句,是否有必要?或者如果我在第一个查询中创建语句就足够了?这对页面速度很重要吗?

有人知道我可以做些什么来让我的应用程序更快吗?

谢谢!

【问题讨论】:

  • JSP 中的数据库连接代码?我想我的眼睛都快融化了。
  • 如何针对 JSP 代码编写单元测试?大概您有大量复制/粘贴的代码“块”?你如何维护它?这只是初学者......
  • 我没有单元测试。是的,我从一个连接复制/粘贴到另一个连接的代码并修改了查询。但如果我不这样做,我该怎么办?如何从数据库中获取数据?因为我在模型中做不到...
  • 这听起来像是一场灾难。删除它并重新开始。也许读一本关于 MVC 或 MVP 或任何软件设计原则的书。
  • 你会不会帮我?我知道如何做一个 MVC,我只想改进这个,我不想做一个新的。如果我制作了一个新的应用程序,我应该怎么做?因为你只说我做的不好,不说哪个是对的……

标签: mysql database jsp web-applications mysql-connector


【解决方案1】:

一个Statement st = conexion.createStatement(); 就足够了。不要继续重新创建语句。您只能调用 createStatement 的次数有限。如果您需要嵌套查询,请创建两个语句 st 和 st2,但不要为同一个变量继续调用 createStatement。

另外,如果你打算在 scriptlet 中使用连接,你至少应该创建一个类来放入实际的连接部分,即Class.forName("org.gjt.mm.mysql.Driver"); Connection conexion = DriverManager.getConnection(....);,然后在 JSP 中调用它。这样一来,您就不会在每个 JSP 中都有凌乱的连接代码,并且当您必须更改服务器 IP 或用户名之类的东西时,您就不必更改大量 JSP。

并且不要在一个 JSP 中打开连接 10 次。你甚至不想在 Servlet 中这样做。您可能希望创建一个 Connection 类型的成员变量,打开它,并保持打开状态,直到结束。

如果你打算使用 scriptlet,你的代码至少应该是这样干净的:

<%
//call a static method in a class you create to get the connection
Connection connection = Appname.dbclass.getConnection();
if(connection==null)
{
   out.print("error connecting");
   return;
}
Statement st = connection.createStatement();
ResultSet rs = null;
...
//do all your stuff
...
if(rs!=null)
{
   try
   {
     rs.close();
   }
   catch(Exception ex){}
}
if(st!=null)
{
   try
   {
     st.close();
   }
   catch(Exception ex){}
}
if(connection!=null)
{
   try
   {
     connection.close();
   }
   catch(Exception ex){}
}
%>

另外,不要执行“从表中选择 *”,然后执行以下操作:

while (rs.next()){
  aaa = rs.getObject("aaa").toString();
 }

在 SQL 中使用 WHERE CLAUSE 将返回的行数限制为 ONE,并将提取的字段限制为所需的字段(“从表 WHERE id=1 中选择 aaa”),然后是 if 语句:

  if (rs.next()){
   aaa = rs.getObject("aaa").toString();
  }

使用您当前的代码,每次您再次执行循环时,都会用新值覆盖 aaa。它浪费了大量的处理时间,要么什么都不做,要么确保结果完全错误。

【讨论】:

  • 抱歉,这几天太忙了,没办法试一试。我将在今天和明天尝试此代码。我不明白你的解释。你说我必须做一个类来放置实际的连接部分。好的,我明白为什么,这很有意义,我想在一开始就做这个,但我不知道这是可能的,但我的问题是,我必须在哪里上课?我怎么能做到呢?我怎么称呼它? PD:谢谢你的回复。
  • 你可以把它放在WEB-INF/classes/YourPackageName/下,确保该类的代码以package YourPackageName;开头,在你的JSP中你可以通过YourPackageName.className来调用它。如果将返回 Connection 的方法设为静态方法,则可以像 YourPackageName.className.methodName(); 一样调用
  • 我已经尝试过这段代码,运行良好,谢谢!另一个问题。你为什么说我应该使用 if 而不是 while 从数据库中获取数据?如果查询只返回 1 行,while 就像 if,只输入一次。但有时查询返回更多我必须保存的值,所以我需要超过 1 次迭代,所以我需要一段时间,而不是 if。显然,我在查询中有一个 where 子句,但这里我没有放它,因为这只是一个示例。再次感谢!
  • while (rs.next()){aaa=rs.getObject("aaa").toString();} out.print(aaa); 将打印多少个值?只有一个。如果你真的需要一个循环,你需要在循环中进行操作。只有一个 assignment 的循环完全是对 CPU 的浪费。如果它循环了 10 次,9 个值就会消失,并且不会对它们进行任何处理,除非它们需要时间。
  • 是的,在这种情况下只会打印循环的最后一个值。但是当我想保存所有的值时,我把它放到一个列表中,所以我保存了所有的值,我是对的吗?当我只想要 1 个值时,while 和 if 有什么区别?这两个操作都只会输入一次,对吧?我会检查所有的查询,但我认为在我想要超过 1 个值的查询中,我把它放在一个列表中,而在其余的查询中,查询只返回一个值,所以我认为它是一样的就像一个如果。
猜你喜欢
  • 2013-08-05
  • 2013-06-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-07
  • 2011-09-06
  • 1970-01-01
相关资源
最近更新 更多