Java SQL Закрытие выписки - PullRequest
       5

Java SQL Закрытие выписки

0 голосов
/ 29 апреля 2020

У меня есть простая Java программа, которая слушает команды и затем выполняет SQL запросы. Программа имеет следующую структуру:

  • Подключение к базе данных при запуске
  • Выполнение запроса SQL для создания TABLE ЕСЛИ НЕ СУЩЕСТВУЕТ (First Statement)
  • Прослушать команду foo и запустить foo(cmd) метод
    • Выполнить SQL запрос внутри этого метода (Second Statement)
    • Это может повторяться несколько раз
  • Закрыть соединение, когда программа убита

Мой вопрос, как обработать Statements. Должен ли я create->execute->close для каждого запроса? Или я должен создать один Statement и использовать его несколько раз (statement.execute();), пока я не остановлю приложение?

Я спрашиваю, потому что мой MySQL сервер иногда очень сильно отстает, и я думаю, что его, потому что у меня слишком много незакрытых операторов или соединений пула.

Я также иногда получаю сообщение об ошибке:

java. sql .SQLException: Операции запрещены после закрытия оператора.

1 Ответ

3 голосов
/ 29 апреля 2020
  1. Вы должны редко использовать Statement; Вы почти всегда хотите PreparedStatement. Использование Statement означает, что вы не можете вводить какой-либо пользовательский ввод в оператор. Если вы попытаетесь, например: statement.executeQuery("SELECT * FROM users WHERE username = '" + userInput + "'");, вы только что написали утечку в системе безопасности. Что, если пользователь отправит в качестве ввода: "foo'; DROP TABLE users; EXECUTE SHELL 'rm -rf /'; --"? - единственный выход - это избежать его, а PreparedStatement - как это сделать.

  2. соединения - это ресурсы; они должны быть закрыты. То же самое можно сказать и о заявлениях (даже подготовленных), а также о наборах результатов. Каждый из них должен рассматриваться как ресурс.

Для работы с ресурсами вы пишете такой код:

try (Connection con = DriverManager.getConnection(...)) {
    try (PreparedStatement ps = con.prepareStatement("SELECT * FROM users WHERE username = ?")) {
        ps.setString(1, username);
        try (ResultSet rs = ps.executeQuery()) {
            while (rs.next()) {
                // handle a row worth of results here
            }
        }
    }
}

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...