JDBC ResultSet получить столбцы с псевдонимом таблицы - PullRequest
46 голосов
/ 29 августа 2011

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

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

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

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

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

Ответы [ 7 ]

45 голосов
/ 29 августа 2011

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: См. Столбец position в вашем вызове JDBC API:

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

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


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

13 голосов
/ 03 января 2014

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

(изменить) пример примера, заявленный Бхаралом в комментарии

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

ResultSetMetaData rsmd = rset.getMetaData();
rsmd.getColumnLabel(1);
8 голосов
/ 29 августа 2011

Используйте псевдонимы столбцов, такие как:

SELECT A.ID 'A_ID', B.ID 'B_ID' FROM TABLE1 AS A, TABLE2 AS B...

И укажите все столбцы, которые вы извлекаете (это хорошая практика).

5 голосов
/ 13 декабря 2016

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

&useOldAliasMetadataBehavior=true

для вашей строки подключения.

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

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

}
1 голос
/ 24 апреля 2012

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

0 голосов
/ 14 октября 2011

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

0 голосов
/ 29 августа 2011

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

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

String value = rs.getString(1);
...