Hibernate NativeQuery setParameter не работает при получении списка таблиц - PullRequest
0 голосов
/ 05 января 2020

Я пытаюсь получить ArrayList таблиц из базы данных MySQL. Из статей, которые я прочитал, следующий код должен работать, но он не работает.

private ArrayList<String> makeTableArray(String dbName){
    ArrayList<String> stringArr = new ArrayList<>();
    try(Session session = ServerConnect.getSessionFactory().openSession()){
        String query = "show tables from :dbName";
        NativeQuery nativeQuery = session.createNativeQuery(query);
        nativeQuery.setParameter("dbName", dbName);
        List list = nativeQuery.list();

        for(Object database: list){
            stringArr.add(String.valueOf(database));
        }
    }
    return stringArr;
}

Ошибка, которую я получаю, используя базу данных sakila:

ОШИБКА: у вас есть ошибка в вашем синтаксисе SQL; обратитесь к руководству, соответствующему вашей MySQL версии сервера, чтобы найти правильный синтаксис для использования рядом с '' sakila '' в строке 1

. Я могу получить это, если объединю запрос с dbName, например как "show tables from " + dbName;, но если я установлю параметр, он не будет работать.

1 Ответ

1 голос
/ 05 января 2020

Нельзя использовать параметры для объектов базы данных, такие как имена таблиц. Ваш подготовленный оператор операторов SQL базы данных не поддерживает его, и если он это сделает, это приведет к серьезным уязвимостям. Вот один из возможных обходных путей, использующий оператор switch:

ArrayList<String> stringArr = new ArrayList<>();
try (Session session = ServerConnect.getSessionFactory().openSession()) {
    String query = "";
    switch (dbName) {
        case "sakila":
            query = "SHOW TABLES FROM sakila";
            break;

        case "foo":
            query = "SHOW TABLES FROM foo";
            break;

        // other database names go here
    }

    NativeQuery nativeQuery = session.createNativeQuery(query);
    nativeQuery.setParameter("dbName", dbName);
    List list = nativeQuery.list();

    for(Object database: list){
        stringArr.add(String.valueOf(database));
    }
}

Идея состоит в том, чтобы просто поддерживать список известных баз данных, которые вы ожидаете получить извне. Затем вы просто сопоставляете имя входящей базы данных с оператором show tables.

...