Эффективный способ обработки 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 ответов
- Итерация по ResultSet
- Создайте новый объект для каждой строки, чтобы хранить нужные вам поля
- Добавьте этот новый объект в ArrayList или Hashmap, или как вам нравится.
- Закройте 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;
}