1

我有这个问题:首先,我使用 Java 执行 SQL 查询,然后将结果存储到名为 rs 的 resultSet() 中。查询如下:

"select ad_id, publisher_id, date, impressions, clicks from table"

然后我使用以下方法读取所有数据:

while(rs.next()){
    (...)
}

问题是我们正在运行的代码需要多次重复使用来自 rs 的所有信息(运行随机梯度,因此有几次迭代)但是当它开始新的迭代(从迭代 1 到 2)时,rs 现在是 null我们必须再次执行 SQL 查询,这需要相当长的时间......

是否有一些“直接”的方法可以将此查询的结果保存到变量中?我们考虑创建两个 ArrayList 来保存整数数字(ad_id、publisher_id ...)和一个用于日期字段,然后遍历这些列表,但我们认为也许有更好、更简单的方法来做到这一点

在 python 中,我们所要做的就是:

data = cursor.fetchall()

并且变量“data”可以多次使用,也许Java中有类似的东西(我还在学习Java,所以我不确定)

谢谢你的帮助

4

3 回答 3

2

在 Java 中,ResultSet 对象是一个只能向前移动的游标,并且只能迭代一次。因此,如果您想多次使用它,您可以将结果存储到临时变量(如列表)中。

最好遵循一些面向对象的方法来存储结果,而不是在 HashMap 中使用松散耦合的数组或键值对。

首先,您应该将数据封装到 Java 对象中,例如创建这样的类

public class ClickInfo {
  private int ad_id;
  private int publisher_id;
  private Date date;
  private int impressions;
  private int clicks;

  // Create getter and setter functions for the instance variabless


}

读取数据库并创建ClickInfo对象并将其存储在数组中。

List<ClickInfo> list = new ArrayList<ClickInfo>();

while (rs.next()) {
  ClickInfo clickInfo = new ClickInfo();
  clickInfo.setAdId(rs.getInt("ad_id"));
  ...
  list.add(clickInfo);
}

现在,您可以多次遍历列表以访问数据

for (ClickInfo cInfo : list)
  System.out.println(cInfo.getAdId());

编辑:上面的示例将结果存储在 ArrayList 中,ClickInfo 对象可以存储在对您的应用程序有意义的任何数据结构中。

于 2012-06-26T23:37:59.000 回答
2

如果您的 JDBC ResultSet 是可滚动的(我认为是在 JDBC v2 中引入的),您可以通过调用 ResultSet 本身来重用ResultSet#beforeFirst,而不必从中复制数据。例子:

Statement stmt = dbconx.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
                                        ResultSet.CONCUR_READ_ONLY);
ResultSet rs = stmt.executeQuery(sql);
while (rs.next()) {
  // do stuff
}
// when finished you can reuse the ResultSet by calling beforeFirst()
rs.beforeFirst();

while (rs.next()) {
  // do more stuff
}
rs.beforeFirst();
// etc.

我已经让它与 MySQL JDBC 驱动程序一起使用。我在 PostgreSQL 驱动程序上进行了尝试,该驱动程序不支持 Scrollable ResultSets,因此如果您的驱动程序不支持它,您需要将结果缓存在某个 Collection 中,正如此处的其他答案所描述的那样。

如果是可滚动的,也可以看上面链接中的absoluterelative方法跳转到ResultSet中的任意点,在某些场景下可能会有用。

更新:正如 Will 在下面的评论中指出的那样 - 您可能需要在您的附加参数createStatement中使 ResultSet 可滚动。我已将其添加为上面的第一行代码。

于 2012-06-26T23:54:19.247 回答
1

您最好的选择是完全按照您所说的将其保存到多维列表中。

这是一个非常基本的功能:

数据成员:

List<List> multiDimensionalList = new ArrayList();

功能:

while(rs.next()){
//create temporary list
List tempList = new ArrayList();
//add results to temporary list
tempList.add(rs.getInt("ad_id")); 
...
//add temporary list to your multidimensionallist
multiDimensionalList.add(tempList);
}
于 2012-06-26T23:13:53.807 回答