Java 如何保存SQL查询的结果集以便多次使用?

Java 如何保存SQL查询的结果集以便多次使用?,java,resultset,Java,Resultset,我有一个问题:首先,我使用Java执行SQL查询,然后将结果存储到名为rs的resultSet()中。查询如下: "select ad_id, publisher_id, date, impressions, clicks from table" 然后,我使用以下方法读取所有数据: while(rs.next()){ (...) } 问题是,我们正在运行的代码需要多次重复使用来自rs的所有信息(运行随机梯度,因此有几次迭代),但当它开始新的迭代(从迭代1到2)时,rs现在为空,我们必

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

"select ad_id, publisher_id, date, impressions, clicks from table"
然后,我使用以下方法读取所有数据:

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

是否有某种“直接”的方法将查询结果保存到变量中?我们考虑创建两个ArrayList来保存整数(ad_id,publisher_id…),一个用于日期字段,然后迭代这些列表,但我们认为可能有更好更简单的方法来实现这一点

在python中,我们需要做的是:

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


感谢您的帮助

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

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

数据成员:

List<List> multiDimensionalList = new ArrayList();

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

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

数据成员:

List<List> multiDimensionalList = new ArrayList();

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

最好采用某种面向对象的方法来存储结果,而不是在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);
}

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

在Java中,ResultSet对象是一个只向前移动的光标,您只能迭代一次。因此,如果您想多次使用它,您必须将结果存储到临时变量(如list)中

最好采用某种面向对象的方法来存储结果,而不是在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);
}
EDIT:上面的示例将结果存储在ArrayList中,ClickInfo对象可以存储在对应用程序有意义的任何数据结构中。

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

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驱动程序上尝试了它,但其中一个不支持可滚动的结果集,因此,如果驱动程序不支持它,则需要将结果缓存在某个集合中,如其他答案所述

如果它是可滚动的,您还可以查看上面链接中的
absolute
relative
方法,跳转到结果集中的任意点,这在某些情况下可能很有用

更新:正如威尔在下面的评论中指出的那样-您可能需要在
createStatement
中添加额外的参数以使结果集可滚动。我在上面的第一行代码中添加了它。

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

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驱动程序上尝试了它,但其中一个不支持可滚动的结果集,因此,如果驱动程序不支持它,则需要将结果缓存在某个集合中,如其他答案所述

如果它是可滚动的,您还可以查看上面链接中的
absolute
relative
方法,跳转到结果集中的任意点,这在某些情况下可能很有用


更新:正如威尔在下面的评论中指出的那样-您可能需要在
createStatement
中添加额外的参数以使结果集可滚动。我已将其添加为上面的第一行代码。

Tnx请大家帮忙!这个答案在这里正好奏效。需要指出的是,我必须使用createStatement并通过键入:statement=connection.createStatement(ResultSet.TYPE\u SCROLL\u不敏感,ResultSet.CONCUR\u只读)将其设置为可滚动的;然后rs=statement.executeQuery(“选择…”)。工作得很有魅力!多谢各位much@Will-打得好。我将这些参数添加到我的createStatement中,现在我的PostgreSQL JDBC连接也可以滚动。我将把这个添加到我的答案中,供将来阅读此文章的其他人参考。谢谢大家的帮助!这个答案在这里正好奏效。需要指出的是,我必须使用createStatement并通过键入:statement=connection.createStatement(ResultSet.TYPE\u SCROLL\u不敏感,ResultSet.CONCUR\u只读)将其设置为可滚动的;然后rs=statement.executeQuery(“选择…”)。工作得很有魅力!多谢各位much@Will-打得好。我将这些参数添加到我的createStatement中,现在我的PostgreSQL JDBC连接也可以滚动。我将把这个添加到我的答案中,以供将来阅读此文章的其他人参考。