Подтвердить что ты не робот

JDBC ResultSet получает столбцы с псевдонимом таблицы

Представьте, что у меня есть запрос типа

SELECT * from table1 a, table2 b where (WHATEVER)

Возможно, обе таблицы имеют одинаковое имя столбца. Поэтому, хотя было бы неплохо получить доступ к данным через

resultSet.getString("a.columnName");
resultSet.getString("b.columnName");

Но это наводит меня на меня, и я ничего не получаю. Я прочитал API, но они действительно не говорят об этом случае. Является ли такая функция зависимой от поставщика?

4b9b3361

Ответ 1

JDBC просто укажет столбцы на то, что указано в запросе, - оно не знает имена таблиц и т.д.

У вас есть два варианта:

Вариант 1: Назовите столбцы по-разному в запросе, то есть

SELECT
    a.columnName as columnNameA,
    b.columnName as columnNameB,
    ...
from table1 a, table2 b where (WHATEVER)

то в вашем java-коду ссылаются на псевдонимы столбцов:

resultSet.getString("columnNameA");
resultSet.getString("columnNameB");


Вариант 2: Обратитесь к позиции столбца в вашем вызове API JDBC:

resultSet.getString(1);
resultSet.getString(2);

Обратите внимание, что JDBC API использует однонаправленные индексы - то есть они подсчитываются от 1 (не от 0, как java-индексы), поэтому используйте 1 для первого столбца, 2 для второго столбца, и т.д.


Я бы рекомендовал вариант 1, потому что безопаснее ссылаться на именованные столбцы: кто-то может изменить порядок столбцов в запросе, и он будет тихо нарушать ваш код (вы будете обращаться к неправильному столбцу, но не знаете), но если они измените имена столбцов, вы, по крайней мере, получите исключение "без такого столбца" во время выполнения.

Ответ 2

ResultSetMetadata.getColumnLabel() - это то, что вам нужно

(редактировать) пример примера, как указано bharal в комментарии

SELECT * from table1 a, table2 b where (WHATEVER)

ResultSetMetaData rsmd = rset.getMetaData();
rsmd.getColumnLabel(1);

Ответ 3

Используйте псевдонимы столбцов, например SELECT A.ID 'A_ID', B.ID 'B_ID' FROM TABLE1 AS A, TABLE2 AS B..., и укажите все столбцы, которые вы извлекаете (это хорошая практика).

Ответ 4

Если вы используете MySQL, просто добавьте

&useOldAliasMetadataBehavior=true

на ваш connectionString.

Впоследствии вы можете использовать этого маленького помощника:

import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;

public class ResultSetHelper {

    private final Map<String, Integer> columnMap;

    public ResultSetHelper(ResultSet rs) throws SQLException {
        this.columnMap = new HashMap<>();
        ResultSetMetaData md = rs.getMetaData();
        int columnCount = md.getColumnCount();
        for (int index = 1; index <= columnCount; index++) {
            String columnName = md.getColumnLabel(index);
            if (!columnMap.containsKey(columnName)) {
                columnMap.put(columnName, index);
            }

            String tableAlias = md.getTableName(index);
            if (tableAlias != null && !tableAlias.trim().isEmpty()) {
                columnMap.put(tableAlias + "." + columnName, index);
            }
        }
    }

    public Integer getColumnIndex(String columnName) {
        return columnMap.get(columnName);
    }

    public Integer getColumnIndex(String tableAlias, String columnName) {
        return columnMap.get(tableAlias + "." + columnName);
    }

}

Ответ 5

Вы можете использовать псевдоним на уровне SQL. Затем вы извлекаете данные по индексам. (Но этот подход сделает обслуживание настоящим кошмаром)

SELECT a.column, b.column FROM table1 a, table2 b

String value = rs.getString(1);

Ответ 6

Одна из моих идей заключалась в том, чтобы использовать getTableName(iCol) для захвата имен таблиц для столбцов с одинаковым именем, а затем обернуть хеш ваших собственных ключей (с префиксом имени таблицы), который укажет вам на правильный индекс столбца, и ссылайтесь на свои значения столбца таким образом. Это потребовало бы первоначального цикла метаданных в начале настройки. Единственная проблема, с которой я вижу, - это то, что вы также называете имена таблиц. Я еще не нашел способ получить эти псевдонимы табличных имен из jdbc, не управляя им самостоятельно, когда вы строите инструкцию sql. Это решение будет зависеть от того, какой синтаксический выигрыш будет для вас.

Ответ 7

Хорошо, похоже, нет такого метода, как resultSet.getString("a.columnName"); и вы должны использовать свои столбцы на уровне sql, но поскольку существует метод getTableName(iCol), я надеюсь, что ребята в java.sql.ResultSet добавить такую ​​функцию.