javajdbc

Build map with column name and column values from java.sql.ResultSet


I have the following snippet:

    Connection connection = getConnection(schemaName);
    Statement stmt = connection.createStatement();
    String sql = "SELECT * FROM " + tableName;
    ResultSet rs = stmt.executeQuery(sql);

now what I want to achieve is building a

Map<String , List<String>>

where key is the columnName and value is list of columnValues. Here is my code:

    ResultSetMetaData rsmd = rs.getMetaData();
    int columnCount = rsmd.getColumnCount();

    List<String> columnNames = new LinkedList<>();
    for (int i = 1; i <= columnCount; i++) {
        columnNames.add(rsmd.getColumnName(i));
    }

    Map<String, List<String>> columnNameToValuesMap = new HashMap<String, List<String>>();

    for (String columnName : columnNames) {
        List<String> values = new ArrayList<>();
        try {
            while (rs.next()) {
                values.add(rs.getString(columnName));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        columnNameToValuesMap.put(columnName, values);
    }

The issue is that after the first columnName iteration, rs.next() is empty. So basically The result map contains the values for only the first column. How can I reuse the same resultSet for each iteration ? Why its empty after the first one ?


Solution

  • You can follow the below steps:

    1. Initialise the columnNameToValuesMap with empty list objects with column name as key

    2. Iterate the resultset using rs.next()

    3. Get each column data using a for loop and add to list values object

    4. Add the list of columns data to columnNameToValuesMap object

    You can refer the below code with comments:

    List<String> columnNames = new LinkedList<>();
    Map<String,List<String>> columnNameToValuesMap=new HashMap<String, List<String>>();
    
    for (int i = 1; i <= columnCount; i++) {
           String columnName = rsmd.getColumnName(i);
           columnNames.add(columnName);
    
           //Load the Map initially with keys(columnnames) and empty list
           columnNameToValuesMap.put(columnName, new ArrayList());
    }
    
    try {
       while (rs.next()) { //Iterate the resultset for each row
    
         for (String columnName : columnNames) {
            //Get the list mapped to column name
            List<String> columnDataList = columnNameToValuesMap.get(columnName);
    
             //Add the current row's column data to list
             columnDataList.add(rs.getString(columnName));
    
             //add the updated list of column data to the map now
             columnNameToValuesMap.put(columnName, columnDataList);
           }
        }
    } catch (SQLException e) {
       e.printStackTrace();
    }