Возможно ли передать набор результатов в Java? - PullRequest
1 голос
/ 30 апреля 2019

Я пытаюсь создать команду, в которой я могу отправлять различные запросы в БД SQLite / Mysql и возвращать набор результатов любой вызываемой функции. Он должен быть в состоянии обрабатывать, есть ли 2 столбца или 15.

Нижеследующее не работает - возможно потому, что оно закрывает набор результатов / соединение, но я не уверен, как еще это сделать.

Мысли

public static ResultSet queryDB(String query) {
    try {
        Connection connection = DriverManager.getConnection("jdbc:sqlite:" + Settings.SQLITE_DB_PATH);
        Statement statement = connection.createStatement();
        ResultSet resultSet = statement.executeQuery(query);
        resultSet.close();
        statement.close();
        connection.close();
        return resultSet;
    } catch (SQLException ex) {
        Logger.getLogger(SQLInterp.class.getName()).log(Level.SEVERE, null, ex);
    }
    return null;
}

1 Ответ

3 голосов
/ 30 апреля 2019

Обычно у вас есть 3 варианта:

  1. Не закрывайте ResultSet, Statement и Connection в методе, передавая ответственность за это обратновызывающий.

    Не рекомендуется , так как он подвержен ошибкам и нарушает парадигмы правильной структуры кода.

  2. Передача объектас логикой, необходимой для обработки данных, как , предложенное Джейкобом Г. .

    Например, используйте Java 8+ Consumer:

    public static void queryDB(String query, Consumer<ResultSet> processor) {
        try (
            Connection connection = DriverManager.getConnection("jdbc:sqlite:" + Settings.SQLITE_DB_PATH);
            Statement statement = connection.createStatement();
            ResultSet resultSet = statement.executeQuery(query);
        ) {
            processor.accept(resultSet);
        } catch (SQLException ex) {
            Logger.getLogger(SQLInterp.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    

    Затем назовите это так:

    SQLInterp.queryDB("SELECT * FROM foo", rs -> {
        while (rs.next()) {
            // process data here
        }
    });
    
  3. Считайте все данные в память в общей структуре данных, например, List<Map<String, Object>>:

    Этоконечно, предполагается, что запрос имеет хорошие уникальные имена для каждого столбца.

    public static List<Map<String, Object>> queryDB2(String query) {
        try (
            Connection connection = DriverManager.getConnection("jdbc:sqlite:" + Settings.SQLITE_DB_PATH);
            Statement statement = connection.createStatement();
            ResultSet resultSet = statement.executeQuery(query);
        ) {
            ResultSetMetaData metaData = resultSet.getMetaData();
            int columnCount = metaData.getColumnCount();
            String[] name = new String[columnCount];
            for (int i = 0; i < columnCount; i++)
                name[i] = metaData.getColumnLabel(i + 1);
            List<Map<String, Object>> rows = new ArrayList<>();
            while (resultSet.next()) {
                Map<String, Object> row = new LinkedHashMap<>();
                for (int i = 0; i < columnCount; i++)
                    row.put(name[i], resultSet.getObject(i + 1));
                rows.add(row);
            }
            return rows;
        } catch (SQLException ex) {
            Logger.getLogger(SQLInterp.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...