在MultiDimensional HashMap中存储来自MySQL查询的多行

时间:2015-10-07 22:11:44

标签: java mysql hashmap

所以我试图将MySQL查询结果集存储到列出的多维HashMap中:

  public HashMap<String, HashMap<String, String>> getData(String query)
  {
     Statement stmt = null;
     HashMap<String, HashMap<String, String>> results = new HashMap<String, HashMap<String, String>>();

     try
     {
        stmt = conn.createStatement();
        ResultSet rs = stmt.executeQuery(query);
        ResultSetMetaData rsmd = rs.getMetaData();

        while (rs.next())
        {
           for (int i = 1; i < rsmd.getColumnCount() + 1; i++)
           {
              results.put(Integer.toString(i - 1), new HashMap<String, String>());
              results.get(Integer.toString(i - 1)).put(rsmd.getColumnLabel(i), rs.getString(i));
           }
        }
     }
     catch (SQLException ex)
     {
        ex.printStackTrace(System.out);
     }

     return results;
  }

然而,当使用该功能将其打印出来时:

   public static void printMap(Map mp)
   {
       Iterator it = mp.entrySet().iterator();

       while (it.hasNext())
       {
           Map.Entry pair = (Map.Entry)it.next();
           System.out.println(pair.getKey() + " = " + pair.getValue());
           it.remove();
       }
   }

它只存储单行结果,我无法理解为什么。

0 = {Date=2014-11-04}
1 = {Num=1256}
2 = {ATime=null}
3 = {ALocCode=null}
4 = {DTime=1:00 PM}
5 = {DLocCode=JFK}
6 = {EstATime=8:00 PM}
7 = {EstDTime=1:00 PM}
8 = {EId=7624}

我的问题是,我能说的唯一方法是与PHP有关,我怎样才能让它像这样存储?

$result[0]['Date'] = '3214';
....
$result[1]['Date'] = '6426';

因为这基本上是我想要实现的目标吗?

2 个答案:

答案 0 :(得分:2)

你交换了“rows”和“columns”的主要问题,接下来就是你每次放置字段时都重新创建HashMap,正确的代码如下所示:

public Map<String, Map<String, String>> getData(final String query) {
    final Map<String, Map<String, String>> results = new HashMap<>();

    try (final Statement stmt = this.conn.createStatement(); final ResultSet rs = stmt.executeQuery(query);) {
        final ResultSetMetaData rsmd = rs.getMetaData();
        long rId = 0;
        while (rs.next()) {
            final Map<String, String> record = new HashMap<>();
            for (int i = 1; i < (rsmd.getColumnCount() + 1); i++) {
                record.put(rsmd.getColumnLabel(i), rs.getString(i));
            }
            results.put(String.valueOf(rId++), record);
        }
    } catch (final SQLException ex) {
        ex.printStackTrace(System.out);
    }

    return results;
}

public static void printMap(final Map<?, ?> mp) {
    for (final Entry<?, ?> entry : mp.entrySet()) {
        final Object key = entry.getKey();
        final Object value = entry.getValue();
        if (value instanceof Map) {
            System.out.println(key);
            printMap((Map<?, ?>) value);
        } else {
            System.out.println(key + "=" + entry.getValue());
        }
    }
}

答案 1 :(得分:1)

Lashane的答案对于你需要解决的错误是有益的,但是可以改进:

  • 您希望对行进行数字访问($result[0]['Date']),而不是字符串。
  • print方法应使用完全类型化的参数。
  • 行应存储在TreeMapLinkedHashMapArrayList中以保留行顺序。实际上ArrayList对你的情况更好。
  • 列应存储在LinkedHashMap中以保留列顺序。
  • 捕获异常并继续。允许它级联到调用者。

更新版本:

public List<Map<String, String>> getData(final String query) throws SQLException {
    final List<Map<String, String>> results = new ArrayList<>();
    try (Statement stmt = this.conn.createStatement();
         ResultSet rs = stmt.executeQuery(query)) {
        ResultSetMetaData metaData = rs.getMetaData();
        while (rs.next()) {
            Map<String, String> record = new LinkedHashMap<>();
            for (int col = 1; col <= metaData.getColumnCount(); col++)
                record.put(metaData.getColumnLabel(col), rs.getString(col));
            results.add(record);
        }
    }
    return results;
}

public static void printMap(List<Map<String, String>> rows) {
    for (int rowNum = 0; rowNum < rows.size(); rowNum++)
        System.out.println(rowNum + " = " + rows.get(rowNum));
}

您现在可以像在PHP中一样访问它:

// PHP (for reference, the way you requested)
$result[0]['Date']

// Java
result.get(0).get("Date")

// Groovy
result[0]['Date']
result[0].Date

// JSP
<c:forEach var="row" items="${result}" varStatus="rowStatus">
  ${rowStatus.index} = <c:out value="${row.Date}"/>, ...
</c:forEach>