【问题标题】:Prepare statement inside a loop循环内的准备语句
【发布时间】:2014-06-29 16:37:38
【问题描述】:

我尝试在循环中执行查询。
我正在尝试这段代码:

public List<Products> DisplayProducts(String []a)
{
    ResultSet rs = null;
      List<Products> Data=null;
    try
    {
    for(int i=0;i<a.length;i++)
    {
         String query = "select  * from products where Brand=?";
        PreparedStatement stmt=DataBaseConnection.DBConn.getConnection().prepareStatement(query);
        stmt.setString(1, a[i]);


        rs=stmt.executeQuery();
       }
       if(rs.next())
       {
           rs.beforeFirst();
          Data=new ArrayList<Products>();
       while(rs.next())
       {
           Products p=new Products();
           p.setTitle(rs.getString(2));
           p.setCategory(rs.getString(3));
           p.setSubCategory(rs.getString(4));
           p.setSubCategoryTwo(rs.getString(5));
           p.setPrice(rs.getInt(6));
           p.setFlavour(rs.getString(7));
           p.setImage(rs.getString(8));
           p.setBrand(rs.getString(9));
           p.setInstock(rs.getString(10));
           p.setInstockQty(rs.getInt(11));
           Data.add(p);

       }
       }
       return Data;

}
    catch(Exception e)
    {

        System.out.println(e.getStackTrace());
        return null;
    }

}

我有一个 jsp 页面,其中有复选框,并且我在此页面上显示多个产品。我正在按 BRANDS 对这些产品进行分类。用户通过选中复选框来选择品牌。

我将复选框的值传递给 servlet 并在该 servlet 调用函数 Display Products 上:

String arr[]=request.getParameterValues("On");     
List<Products> Data=new SessionBeanClass().DisplayProducts(arr);

请告诉我如何执行并得到结果?

【问题讨论】:

  • 您的问题是什么?哪里发生错误?请把问题说得更清楚。
  • 问题是我在执行选择查询时返回一个列表,但我在列表中没有得到任何东西

标签: java sql jsp servlets jdbc


【解决方案1】:

我想您需要返回选中复选框的所有产品列表。在那种情况下,我想你这里有一个逻辑错误。此方法仅返回最后一条 Product 记录。 您可以使用“IN”子句并一次全部返回,而不是遍历不同的 id。有许多不同的方法来实现 IN 子句。下面给出的是一个简单的替代方案。您可以在http://www.journaldev.com/2521/jdbc-preparedstatement-in-clause-alternative-approacheshttp://www.javaranch.com/journal/200510/Journal200510.jsp#a2 中检查各种操作

除此之外,尝试遵循 java 命名约定并使用 finally 清理连接

试试

public List<Products> DisplayProducts(String[] a) {
        ResultSet rs;
        List<Products> data;
        PreparedStatement stmt;
        try {
            StringBuilder param = new StringBuilder();
            for(String str : a){
                param.append("'").append(str).append("', ");
            }
            String query = "select  * from products where Brand in (" + param.substring(0, param.length() - 2) + ")";
            stmt = DataBaseConnection.DBConn.getConnection().prepareStatement(query);
            rs = stmt.executeQuery();
            if (rs != null) {
                data = new ArrayList<Products>();
                while (rs.next()) {
                    Products p = new Products();
                    p.setTitle(rs.getString(2));
                    p.setCategory(rs.getString(3));
                    p.setSubCategory(rs.getString(4));
                    p.setSubCategoryTwo(rs.getString(5));
                    p.setPrice(rs.getInt(6));
                    p.setFlavour(rs.getString(7));
                    p.setImage(rs.getString(8));
                    p.setBrand(rs.getString(9));
                    p.setInstock(rs.getString(10));
                    p.setInstockQty(rs.getInt(11));
                    data.add(p);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            stmt.close();
        }
        return data;
}

根据评论解释

好的。我想您在这里的想法是传递一组品牌名称,例如阿迪达斯、耐克等,然后选择所有产品详细信息。所以你需要做类似select * from products where Brand in ('adidas', 'nike')的事情。这将为您提供所有产品。因此,为此,您将选定的品牌名称作为字符串数组传递。所以我所做的是从数组中获取值并将其格式化并将其作为 IN 子句的参数。所以 IN 子句需要逗号分隔值。由于它是一个 Sting,我们还需要提供单引号 '。所以从数组[adidas, nike] 我需要构造'adidas', 'nike'。这就是在 for 循环中所做的,附加 ' 和 ,(逗号)。因此,在 for 循环之后,我们将在末尾添加一个额外的逗号和空格(例如 'adidas'、'nike'、 )。为了删除它,我通过将子字符串作为param.substring(0, param.length() - 2) 来删除最后两个字符。这被提供给查询并检索结果。

【讨论】:

  • 如果您建议正确关闭连接,为什么不将其添加到您的示例中?使用 try-with-resources 不会变得更大。此外,将数据放入 try 将允许缩小范围并发现 OP 更容易犯的错误(并且也遵循约定)
  • @Ordous :我只是想给出一个简单的例子,而不是一个完整的实现。无论如何,我已经更新了我的答案。谢谢你.. :)
  • 想一想,OP 实际上从未关闭连接或语句/rs,这可能会破坏任何池机制。但你是对的,这与手头的逻辑问题无关。
  • @Syam 有没有什么办法可以通过支票簿退回仅选定品牌的产品。为什么我不能多次执行 Prepare 语句。
  • 这段代码就是这样做的。输入数组应包含所有选定的品牌名称,并返回与该品牌名称匹配的所有产品。您绝对可以多次执行准备好的语句。然而,每次执行实际上都是一次数据库调用,因此最好减少流量以提高性能。
猜你喜欢
  • 2012-08-11
  • 2023-03-23
  • 1970-01-01
  • 2022-01-23
  • 2016-04-08
  • 1970-01-01
  • 1970-01-01
  • 2012-07-07
相关资源
最近更新 更多