Search code examples
javajdbcresultset

Java ResultSet copy to generic object or list


I'm aware of the issues with using ResultSet and have seen examples about extracting data into an object (or list), however, I'm wanting to do this in a generic manner i.e. without having to be aware of the class.

Is there a way to do this such that the result would be an Object or List that I could then iterate using Reflection?

The solutions I've examined that either don't seem to work or require class awareness of the target class include:

I've also tried ResultSetMapper (http://resultsetmapper.sourceforge.net/) and it seems to require the class as well. I really just want an Object or List that I can act on.


Solution

  • This is pretty generic:

    Statement st = con.createStatement();
    ResultSet rs = st.executeQuery("SELECT * FROM Clients WHERE ID <= 2");
    
    // collect column names
    List<String> columnNames = new ArrayList<>();
    ResultSetMetaData rsmd = rs.getMetaData();
    for (int i = 1; i <= rsmd.getColumnCount(); i++) {
        columnNames.add(rsmd.getColumnLabel(i));
    }
    
    int rowIndex = 0;
    while (rs.next()) {
        rowIndex++;
        // collect row data as objects in a List
        List<Object> rowData = new ArrayList<>();
        for (int i = 1; i <= rsmd.getColumnCount(); i++) {
            rowData.add(rs.getObject(i));
        }
        // for test purposes, dump contents to check our results
        // (the real code would pass the "rowData" List to some other routine)
        System.out.printf("Row %d%n", rowIndex);
        for (int colIndex = 0; colIndex < rsmd.getColumnCount(); colIndex++) {
            String objType = "null";
            String objString = "";
            Object columnObject = rowData.get(colIndex);
            if (columnObject != null) {
                objString = columnObject.toString() + " ";
                objType = columnObject.getClass().getName();
            }
            System.out.printf("  %s: %s(%s)%n",
                    columnNames.get(colIndex), objString, objType);
        }
    }
    

    For my test data (in SQL Server) it prints the following to the console:

    Row 1
      ID: 1 (java.lang.Integer)
      LastName: Thompson (java.lang.String)
      FirstName: Gord (java.lang.String)
      DOB: (null)
    Row 2
      ID: 2 (java.lang.Integer)
      LastName: Loblaw (java.lang.String)
      FirstName: Bob (java.lang.String)
      DOB: 1966-09-12 16:03:00.0 (java.sql.Timestamp)