Эффективный способ обработки ResultSet в Java

Я использую ResultSet в Java, и я не уверен, как правильно его закрыть. Я рассматриваю возможность использования 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;
}

9 ответов

Решение
  1. Итерация по ResultSet
  2. Создайте новый объект для каждой строки, чтобы хранить нужные вам поля
  3. Добавьте этот новый объект в ArrayList или Hashmap, или как вам нравится.
  4. Закройте ResultSet, Statement и соединение с БД

Готово

РЕДАКТИРОВАТЬ: теперь, когда вы опубликовали код, я внес в него несколько изменений.

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;
}

Я только очистил ответ 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;
}

RHT в значительной степени имеет это. Или вы можете использовать RowSetDynaClass и позволить кому-то еще делать всю работу:)

Это мое альтернативное решение, вместо списка карт, я использую карту списка. Протестировано на таблицах из 5000 элементов, на удаленной базе данных, время составляет около 350 мс для метода Eiter.

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;
}

Несколько вещей, чтобы улучшить другие ответы. Во-первых, вы никогда не должны возвращать HashMap, который является конкретной реализацией. Верните вместо старого java.util.Map, Но на самом деле это не совсем верно для этого примера. Ваш код возвращает только последнюю строку ResultSet в виде (хэш) карты. Вы вместо этого хотите вернуть List<Map<String,Object>>, Подумайте, как вы должны изменить свой код, чтобы сделать это. (Или вы можете принять предложение Дейва Ньютона).

Я улучшил решения RHTs/Brad Ms и ответа Lestos.

Я расширил оба решения, оставив государство там, где он был найден. Поэтому я сохраняю текущую позицию ResultSet и восстанавливаю ее после создания карт.

Rs - это ResultSet, это переменная поля, поэтому в моих фрагментах решений не отображается.

Я заменил конкретную карту в решении Brad Ms на общую карту.

    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. Я сократил это до только одного доступа к массиву на каждой итерации цикла. Таким образом, программа не должна искать этот строковый ключ на каждом шаге итерации.

    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;
    }

Вы можете использовать приведенный ниже пример, чтобы запустить и понять его основы. Очень простой для понимания полностью рабочий код/пример.

      import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

public class DynamicRows {

    public static void main(String[] args) {
        DynamicRows dr = new DynamicRows();
        List<Map<String, Object>> rows = dr.getSearchRecords();
    }

    public List<Map<String, Object>> getSearchRecords() {
        ResultSet rs = null;
        Connection conn = null;
        List<Map<String, Object>> rows = null;
        try {
            conn = openConnection();
            if (conn != null) {

                java.sql.PreparedStatement ps = conn.prepareStatement("select * from online_users");
                rs = ps.executeQuery();

                if (rs != null) {
                    rows = new ArrayList<Map<String, Object>>();
//Code get resultset metadata information
                    ResultSetMetaData metaData = rs.getMetaData();
//To get column count in result set
                    int columnCount = metaData.getColumnCount();

                    while (rs.next()) {
                        Map<String, Object> columns = new LinkedHashMap<String, Object>();
//System.out.println("=======Row Start Here===========");
                        for (int i = 1; i <= columnCount; i++) {
                            // To get Column Name
                            // System.out.println(metaData.getColumnLabel(i)+"->"+rs.getObject(i));
                            columns.put(metaData.getColumnLabel(i), rs.getObject(i));
                        }

                        rows.add(columns);
                    }
                }
            }

        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
            try {
                if (rs != null) {
                    rs.close();
                }
            } catch (SQLException ex) {
                ex.printStackTrace();
            }
            closeConnection(conn);
        }
System.out.println(rows);
        return rows;
    }

    private Connection openConnection() throws SQLException {
        Connection conn = null;
        try {
            System.out.println("Load JDBC Driver");
            Class.forName("oracle.jdbc.driver.OracleDriver");
        } catch (ClassNotFoundException e) {

            System.out.println("Fail to Load JDBC Driver ");
            e.printStackTrace();
            return null;
        }

        System.out.println("JDBC Driver Registered .");

        conn = employee.DbConnection.getDatabaseConnection();

        if (conn != null) {
            System.out.println("JDBC connection is Successful !");
        } else {
            System.out.println("JDBC Connection failed !");
        }
        return conn;
    }

    private void closeConnection(Connection conn) {
        if (conn != null) {
            try {

                conn.close();
                System.out.println("Connection closed successfully");
            } catch (SQLException ex) {
                System.out.println("Failed to close JDBC Connection !");
                ex.printStackTrace();
            }
        } else {

            System.out.println("No JDBC connection to close !");
        }
    }

}

Выход :

      Load JDBC Driver
JDBC Driver Registered .
JDBC connection is Successful !
Connection closed successfully
[{USERNAME=test, ISACTIVE=False, LOGIN_TIME=2023-08-15 19:01:30.0, LOGOUT_TIME=2023-08-15 19:01:46.0}]

Вот немного измененный код, который я получил от 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();
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;
    }
Другие вопросы по тегам