【问题标题】:How can I pull multiple values from sql database with java.sql?如何使用 java.sql 从 sql 数据库中提取多个值?
【发布时间】:2021-05-25 10:12:12
【问题描述】:

我有一个包含商品的产品编号和其他详细信息的产品表,以及一个包含产品编号、评级和评论的 ReviewTable。因为一个项目可以有多个评分和评论,我需要检索该项目的所有评分和评论。

 "drop table ProductTable", // The product table


"create table ProductTable ("+
      "productNo      Char(4)," + // Unique product number
      "description    Varchar(40)," +
      "picture        Varchar(80)," +
      "price          Float)",

  "insert into ProductTable values " +
     "('0001', '40 inch LED HD TV', 'images/pic0001.jpg', 269.00)",

 "drop table ReviewTable",
   "create table ReviewTable ("+ 
   "productNo       Char(4)," +
   "ratingScore     Integer,"  +
   "review          Varchar(200))",
   
   "insert into ReviewTable values ( '0001',  2, 'Very high quality, but I had to replace it after 1 year' )",
   "insert into ReviewTable values ( '0001',  3, 'Very good' )", // Two reviews for the same product

   "select * from ReviewTable, ProductTable " +
              " where ReviewTable.productNo = ProductTable.productNo",

我有一个 Product 对象,它以产品编号、所有评分数组和评论数组作为参数:

 public Product(String aProductNum, double[] aRating, String[] aReviews) {
      theProductNum  = aProductNum;     // Product number
        theRating      = aRating;         // ratings of product
        theReviews     = aReviews;        // All the reviews for the product
}

最后,我有一个 getDetails 方法来检索有关产品的数据,这就是我需要向数组添加多个值的地方..

  public synchronized Product getDetails( String pNum )
         throws StockException
  {
    try
    {
        String [] reviews = new String[0]; // Initialise reviews
        double [] ratings = new double[0]; // Initialise ratings
      Product   dt = new Product( "0", ratings, reviews); // Initialise product
      ResultSet rs = getStatementObject().executeQuery(
        "select ratingScore, review " +
        "  from ProductTable, ReviewTable " +
        "  where  ProductTable.productNo = '" + pNum + "' " +
        "  and    ReviewTable.productNo  = '" + pNum + "'"
      );
      if ( rs.next() )
      {
        dt.setProductNum( pNum );            
        dt.setRating(rs.getDouble("ratingScore") ); // CURRENTLY PULLING ONLY ONE RATING
        dt.setReviews(rs.getString("review"));  // CURRENTLY PULLING ONLY ONE REVIEW

      }
      rs.close();
      return dt;
    } catch ( SQLException e )
    {
      throw new StockException( "SQL getDetails: " + e.getMessage() );
    }
  }

有什么帮助吗?提前非常感谢

【问题讨论】:

  • dt.setRating() 等似乎只设置了您为整个查询重用的 Product 实例的一个值。如果您想检索多个评论,您需要为此提供代码,例如在Product 中创建Review 类和addReview(Review) 方法,然后使用从结果集中提取的值像dt.addReview(new Review(rating, review)) 一样调用它。稍后您可能希望为此使用适当的 ORM 框架,但这就是您可以开始的方式。
  • 永远不要像这样构建查询,使用带有占位符的准备好的语句。这段代码对于 SQL 注入攻击来说已经成熟了。
  • @Abra 我需要将所有评级的数组和一个用于共享相同productNo 的所有评论的数组作为参数传递给Product 类,如果不清楚,抱歉。我还更改了评论,我的错误 - 我不需要平均评分,而是每个评分的数组。
  • @Abra 对于这个问题,我从我的原始代码中排除了所有不必要的信息,并忘记删除该位,抱歉。现在更新了,应该没问题。

标签: java sql arrays


【解决方案1】:

这是对方法getDetails 的重写。代码后的解释。

请注意,这完全基于您问题中的详细信息。

public synchronized Product getDetails( String pNum )
         throws StockException
{
    String sql = "select ratingScore, review from ReviewTable where productNo = ?";
    try (java.sql.Connection conn = java.sql.DriverManager.getConnection("URL");
         java.sql.PreparedStatement ps = conn.prepareStatement(sql))
    {
        ps.setString(1, pNum);
        ResultSet rs = ps.executeQuery();
        java.util.List<Double> ratings = new java.util.ArrayList<>();
        java.util.List<String> reviews = new java.util.ArrayList<>();
        while ( rs.next() )
        {
            ratings.add(rs.getDouble(1);
            reviews.add(rs.getString(2));
        }
        double[] ratingsArray = ratings.stream().mapToDouble(Double::doubleValue).toArray();
        String[] reviewsArray = reviews.toArray(new String[]{});
        return new Product(pNum, ratingsArray, reviewsArray);
    } catch ( SQLException e )
    {
        throw new StockException( "SQL getDetails: " + e.getMessage() );
    }
}
  • 您应该使用java.sql.PreparedStatement 而不是Statement
  • 上面的代码使用了try-with-resources,因为使用完需要关闭PreparedStatement
  • 由于您只从数据库表 ReviewTable 中检索列,因此我更改了 SQL 查询。
  • 您可以使用while 循环而不是调用if (rs.next())。这样您就可以遍历Resultset 中的所有行。
  • 由于您不知道ResultSet 中有多少行,请使用List 来存储所有行的详细信息。
  • 由于您的类Product 存储一个数组而不是List,因此我将Lists 转换为数组。请注意,将 List&lt;Double&gt; 转换为 double[] 的代码来自这个 SO 问题:How to cast from List to double[] in Java?
  • 现在我有了调用Product 类的构造函数所需的三个参数。所以我调用构造函数,返回构造函数返回的对象。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-07-23
    • 1970-01-01
    • 2016-03-03
    • 2019-01-02
    • 1970-01-01
    • 2013-04-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多