【问题标题】:Efficient way to Handle ResultSet in Java在 Java 中处理 ResultSet 的有效方法
【发布时间】:2011-11-22 08:32:05
【问题描述】:

我在 Java 中使用 ResultSet,但不确定如何正确关闭它。我正在考虑使用 ResultSet 来构造一个 HashMap,然后在此之后关闭 ResultSet。这种 HashMap 技术是有效的,还是有更有效的方法来处理这种情况?我需要键和值,所以使用 HashMap 似乎是一个合乎逻辑的选择。

如果使用 HashMap 是最有效的方法,我该如何在我的代码中构造和使用 HashMap?

这是我尝试过的:

public HashMap resultSetToHashMap(ResultSet rs) throws SQLException {

  ResultSetMetaData md = rs.getMetaData();
  int columns = md.getColumnCount();
  HashMap row = new HashMap();
  while (rs.next()) {
     for (int i = 1; i <= columns; i++) {
       row.put(md.getColumnName(i), rs.getObject(i));
     }
  }
  return row;
}

【问题讨论】:

  • 发布您正在创建哈希映射并填充结果集的代码部分。
  • 误导性方法名称...我看不到 ArrayList。
  • @Deepak:你做的一般都可以,但是你需要在返回之前rs.close()。如果您需要访问整个数据集,则将数据从结果集中复制到 HashMap 是正确的方法。
  • @Zaki:对不起:P
  • 不要关闭此方法中的 ResultSet。 ResultSet 作为参数传递,因此调用者有责任关闭它。并且关闭应该在'finally'块中完成,这样即使抛出异常也能完成。

标签: java hashmap resultset sqlresultsetmapping


【解决方案1】:
  1. 遍历 ResultSet
  2. 为每一行创建一个新对象,以存储您需要的字段
  3. 将此新对象添加到 ArrayList 或 Hashmap 或任何您喜欢的对象
  4. 关闭 ResultSet、Statement 和 DB 连接

完成

编辑:既然您已经发布了代码,我已经对其进行了一些更改。

public List resultSetToArrayList(ResultSet rs) throws SQLException{
  ResultSetMetaData md = rs.getMetaData();
  int columns = md.getColumnCount();
  ArrayList list = new ArrayList(50);
  while (rs.next()){
     HashMap row = new HashMap(columns);
     for(int i=1; i<=columns; ++i){           
      row.put(md.getColumnName(i),rs.getObject(i));
     }
      list.add(row);
  }

 return list;
}

【讨论】:

  • 为什么要列出?为什么我们不能按原样使用 hashmap?
  • @Deepak,因为 List 是数据库中记录的集合,其中每条记录(行)表示为 HashMap,其中每个 hashmap 是列名和记录数据的映射。
  • 好的,我明白了!如果我只使用 HashMap,我将一直只得到一行是吗??
  • 我正在发布我的答案,而你们正在讨论这个问题(没有双关语)。在任何最近的 Java 编译器中,您都会收到不使用类型安全集合的警告。此外,“list”和“row”变量应该使用 List 和 Map 的类型安全版本来声明,而不是 ArrayList 和 HashMap。然后将新的 ArrayList 和 HashMap 实例分配给这些变量。
  • 返回列表> 是一种以行为中心的查看方式。如果您想要以列为中心的视图,请返回一个 Map>,其中键是列名。有时它可能对您更有用。
【解决方案2】:

我刚刚清理了 RHT 的答案以消除一些警告,并认为我会分享。 Eclipse 完成了大部分工作:

public List<HashMap<String,Object>> convertResultSetToList(ResultSet rs) throws SQLException {
    ResultSetMetaData md = rs.getMetaData();
    int columns = md.getColumnCount();
    List<HashMap<String,Object>> list = new ArrayList<HashMap<String,Object>>();

    while (rs.next()) {
        HashMap<String,Object> row = new HashMap<String, Object>(columns);
        for(int i=1; i<=columns; ++i) {
            row.put(md.getColumnName(i),rs.getObject(i));
        }
        list.add(row);
    }

    return list;
}

【讨论】:

  • 使用 while(rs.hasNext()) 代替 .next()?
  • 感谢您的清理,一切正常!
  • @AlexanderMills 如果你使用 rs.hasNext() 那么你将不得不再次在循环中添加 rs.next() 。这样它的 2 鸟 1 石头。
  • 非常感谢@Brad M!通过在相应的行中省略 ArrayList 和 HashMap 的构造函数的类型,甚至可以稍微简化:List&lt;HashMap&lt;String,Object&gt;&gt; list = new ArrayList&lt;&gt;();HashMap&lt;String,Object&gt; row = new HashMap&lt;&gt;(columns);
【解决方案3】:

RHT 几乎拥有它。或者您可以使用RowSetDynaClass 并让其他人完成所有工作:)

【讨论】:

    【解决方案4】:

    这是我的替代解决方案,而不是地图列表,我使用的是列表地图。 在远程数据库上对 5000 个元素的表进行测试,eiter 方法的时间约为 350 毫秒。

    private Map<String, List<Object>> resultSetToArrayList(ResultSet rs) throws SQLException {
        ResultSetMetaData md = rs.getMetaData();
        int columns = md.getColumnCount();
        Map<String, List<Object>> map = new HashMap<>(columns);
        for (int i = 1; i <= columns; ++i) {
            map.put(md.getColumnName(i), new ArrayList<>());
        }
        while (rs.next()) {
            for (int i = 1; i <= columns; ++i) {
                map.get(md.getColumnName(i)).add(rs.getObject(i));
            }
        }
    
        return map;
    }
    

    【讨论】:

    • 我真的很喜欢这个解决方案。我尝试使用 ResultSet.getArray(int columnIndex) 一次获取整个列,但至少对于 com.mysql.cj.jdbc.Driver,这会导致 SQLFeatureNotSupportedException
    【解决方案5】:

    有几件事可以增强其他答案。首先,你永远不应该返回一个HashMap,这是一个特定的实现。而是返回一个普通的旧java.util.Map。但无论如何,这实际上不适合这个例子。您的代码仅将 ResultSet 的最后一行作为 (Hash)Map 返回。相反,您想返回 List&lt;Map&lt;String,Object&gt;&gt;。想想你应该如何修改你的代码来做到这一点。 (或者你可以采纳 Dave Newton 的建议)。

    【讨论】:

      【解决方案6】:

      我改进了 RHT/Brad Ms 和 Lestos 答案的解决方案。

      我扩展了这两种解决方案,将状态留在那里,在那里找到它。 所以我保存当前的 ResultSet 位置并在创建地图后恢复它。

      rs 是 ResultSet,它是一个字段变量,因此在我的解决方案-sn-ps 中不可见。

      我将 Brad Ms 解决方案中的特定 Map 替换为通用 Map。

          public List<Map<String, Object>> resultAsListMap() throws SQLException
          {
              var md = rs.getMetaData();
              var columns = md.getColumnCount();
              var list = new ArrayList<Map<String, Object>>();
      
              var currRowIndex = rs.getRow();
              rs.beforeFirst();
      
              while (rs.next())
              {
                  HashMap<String, Object> row = new HashMap<String, Object>(columns);
                  for (int i = 1; i <= columns; ++i)
                  {
                      row.put(md.getColumnName(i), rs.getObject(i));
                  }
      
                  list.add(row);
              }
      
              rs.absolute(currRowIndex);
      
              return list;
          }
      

      在 Lestos 解决方案中,我优化了代码。在他的代码中,他必须在 for 循环的每次迭代中查找 Maps。我将其减少到每次 for 循环迭代只有一个数组访问。所以程序不能为该字符串键搜索每个迭代步骤。

          public Map<String, List<Object>> resultAsMapList() throws SQLException
          {
              var md = rs.getMetaData();
              var columns = md.getColumnCount();
              var tmp = new ArrayList[columns];
              var map = new HashMap<String, List<Object>>(columns);
      
              var currRowIndex = rs.getRow();
              rs.beforeFirst();
      
              for (int i = 1; i <= columns; ++i)
              {
                  tmp[i - 1] = new ArrayList<>();
                  map.put(md.getColumnName(i), tmp[i - 1]);
              }
      
              while (rs.next())
              {
                  for (int i = 1; i <= columns; ++i)
                  {
                      tmp[i - 1].add(rs.getObject(i));
                  }
              }
      
              rs.absolute(currRowIndex);
      
              return map;
          }
      

      【讨论】:

        【解决方案7】:

        这是我从 google 获得的稍作修改的代码 -

         List data_table = new ArrayList<>();
            Class.forName("oracle.jdbc.driver.OracleDriver");
                    con = DriverManager.getConnection(conn_url, user_id, password);
                    Statement stmt = con.createStatement();
                    System.out.println("query_string: "+query_string);
                    ResultSet rs = stmt.executeQuery(query_string);
                    ResultSetMetaData rsmd = rs.getMetaData();
        
        
                    int row_count = 0;
                    while (rs.next()) {
                        HashMap<String, String> data_map = new HashMap<>();
                        if (row_count == 240001) {
                            break;
                        }
                        for (int i = 1; i <= rsmd.getColumnCount(); i++) {
                            data_map.put(rsmd.getColumnName(i), rs.getString(i));
                        }
                        data_table.add(data_map);
                        row_count = row_count + 1;
                    }
                    rs.close();
                    stmt.close();
                    con.close();
        

        【讨论】:

        • 在ArrayList>的for中返回查询输出
        • 您好,请在您的回答中更具描述性。
        【解决方案8】:
        public static List<HashMap<Object, Object>> GetListOfDataFromResultSet(ResultSet rs) throws SQLException {
                ResultSetMetaData metaData = rs.getMetaData();
                int count = metaData.getColumnCount();
                String[] columnName = new String[count];
                List<HashMap<Object,Object>> lst=new ArrayList<>();
                while(rs.next()) {
                    HashMap<Object,Object> map=new HashMap<>();
                    for (int i = 1; i <= count; i++){
                           columnName[i-1] = metaData.getColumnLabel(i);
                           map.put(columnName[i-1], rs.getObject(i));
                    }
                    lst.add(map);
        
                }
                return lst;
            }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-12-16
          • 2015-02-14
          • 2010-10-26
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多