Говоря как сопровождающий драйвера JDBC (и, я допускаю, сделав несколько широких обобщений, которые не обязательно применяются ко всем драйверам JDBC), значения строк обычно будут храниться в массиве или списке, потому что это наиболее естественно соответствует тому, как данныеполученные от сервера базы данных.
В результате, получение значений по индексу будет самым простым.Это может быть так просто, как что-то вроде (игнорируя некоторые мрачные детали реализации драйвера JDBC):
public Object getObject(int index) throws SQLException {
checkValidRow();
checkValidIndex(index);
return currentRow[index - 1];
}
Это примерно так же быстро, как и получается.
С другой стороны, поиск по имени столбца больше работы.Имена столбцов должны обрабатываться без учета регистра, что сопряжено с дополнительными затратами, независимо от того, нормализуетесь ли вы в нижнем или верхнем регистре или используете поиск без учета регистра, используя TreeMap
.
Простая реализация может выглядеть примерно так:
public Object getObject(String columnLabel) throws SQLException {
return getObject(getIndexByLabel(columnLabel));
}
private int getIndexByLabel(String columnLabel) {
Map<String, Integer> indexMap = createOrGetIndexMap();
Integer columnIndex = indexMap.get(columnLabel.toLowerCase());
if (columnIndex == null) {
throw new SQLException("Column label " + columnLabel + " does not exist in the result set");
}
return columnIndex;
}
private Map<String, Integer> createOrGetIndexMap() throws SQLException {
if (this.indexMap != null) {
return this.indexMap;
}
ResultSetMetaData rsmd = getMetaData();
Map<String, Integer> map = new HashMap<>(rsmd.getColumnCount());
// reverse loop to ensure first occurrence of a column label is retained
for (int idx = rsmd.getColumnCount(); idx > 0; idx--) {
String label = rsmd.getColumnLabel(idx).toLowerCase();
map.put(label, idx);
}
return this.indexMap = map;
}
В зависимости от API базы данных и доступных метаданных оператора, может потребоваться дополнительная обработка для определения фактических меток столбцов запроса.В зависимости от стоимости это, вероятно, будет определено только тогда, когда это действительно необходимо (при доступе к меткам столбцов по имени или при получении метаданных набора результатов).Другими словами, стоимость createOrGetIndexMap()
может быть довольно высокой.
Но даже если эта стоимость незначительна (например, оператор подготовки метаданных с сервера базы данных включает в себя метки столбцов), затраты на сопоставление метки столбца с индексом и последующий поиск по индексу, очевидно, выше, чем прямой поиск поindex.
Драйверы могут даже просто зацикливаться на метаданных набора результатов каждый раз и использовать первый, чья метка совпадает;это может быть дешевле, чем создание и доступ к хэш-карте для наборов результатов с небольшим числом столбцов, но стоимость все равно выше, чем прямой доступ по индексу.
Как я уже сказал, это общее обобщение, ноЯ был бы удивлен, если это (поиск по индексу, а затем поиск по индексу) не так, как это работает в большинстве драйверов JDBC, а это значит, что я ожидаю, что поиск по индексу, как правило, будет быстрее.
Если взглянуть на ряд драйверов, это относится к:
- Firebird (Jaybird, раскрытие: я поддерживаю этот драйвер)
- MySQL (MySQL Connector / J)
- PostgreSQL
- Oracle
- HSQLDB
- SQL Server (драйвер Microsoft JDBC для SQL Server)
Я не в курседрайверов JDBC, где поиск по имени столбца будет эквивалентен по стоимости или даже дешевле.