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

Предпочтительный способ запроса базы данных несколько раз?

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

// load driver
Connection con = DriverManager.getConnection(..);
Statement stmt = con.createStatement();
ResultSet result = stmt.executeQuery("SELECT..");
// ...

Однако я не уверен, как обрабатывать второй запрос в той же базе данных.

  • Можно ли безопасно выполнить другой запрос на одном и том же объекте Statement или создать другой оператор из объекта Connection для выполнения другого запроса?

  • Если для нескольких запросов может использоваться один и тот же объект Statement, какова цель класса Statement (так как тогда было бы разумнее существовать метод Connection.executeQuery())?

4b9b3361

Ответ 1

Да, вы можете повторно использовать объект Statement, но объекты ResultSet, возвращаемые executeQuery, закрывают уже открытые конечные объекты.

См. javadoc для объяснения

По умолчанию может быть открыт только один объект ResultSet для объекта Statement. в то же время. Поэтому, если чтение одного объекта ResultSet чередуются с чтением другого, каждый должен быть сгенерирован различными объектами Statement. Все методы выполнения в Заявлении интерфейс неявно закрывает текущий объект ResultSet, если открытый существует.

Итак, происходит следующее:

// load driver
Connection con = DriverManager.getConnection(..);
Statement stmt = con.createStatement();
ResultSet result = stmt.executeQuery("select ..");
// do something with result ... or not
ResultSet result2 = stmt.executeQuery("select ...");
// result is now closed, you cannot read from it anymore
// do something with result2
stmt.close(); // will close the resultset bound to it

Например, вы можете найти реализацию Statement с открытым исходным кодом в проекте jTDS. В методе Statement.executeQuery() вы можете вызвать вызов initialize(), что уже закрыл все отображаемые результаты

protected void initialize() throws SQLException {
    updateCount = -1;
    resultQueue.clear();
    genKeyResultSet = null;
    tds.clearResponseQueue();
    // FIXME Should old exceptions found now be thrown instead of lost?
    messages.exceptions = null;
    messages.clearWarnings();
    closeAllResultSets();
}

Ответ 2

Программно, вы можете повторно использовать одно и то же соединение и один и тот же оператор для нескольких запросов и закрыть оператор и соединение в конце.

Однако это не очень хорошая практика. Производительность приложения очень чувствительна к способу доступа к базе данных. В идеале каждое соединение должно быть открытым в течение минимального промежутка времени. Затем соединения должны быть объединены. Исходя из этого, вы должны заключить каждый запрос в блок {open connection, create a prepared statement, run query, close statement, close connection}. Это также способ реализации большинства шаблонов SQL. Если concurrency разрешает, вы можете запускать несколько таких запросов одновременно с помощью пула потоков.

Ответ 3

У меня есть одна вещь, которую нужно добавить, если вы используете Connection и Statement в потоковой среде. Мой опыт показывает, что stmt.executeQuery(..) сохраняется для использования в параллельной среде, но с последствием, что каждый запрос сериализуется и, таким образом, обрабатывается последовательно, не давая никаких ускорений. Поэтому лучше использовать новое соединение (не выражение) для каждого потока.

Для стандартной последовательной среды мой опыт показал, что повторное использование заявлений не является проблемой вообще, и ResultSets не нужно закрывать вручную.

Ответ 4

Итак, почему мы имеем понятие классов в объектно-ориентированном программировании. Класс определяет составные элементы, которые позволяют своим экземплярам иметь состояние и поведение. Здесь оператор относится ко всему, что связано с оператором sql. Есть так много функций, которые можно выполнять, например, пакетные запросы и т.д.

Ответ 5

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

Хорошо писать объекты, которые будут обрабатывать такие низкоуровневые (повторяющиеся) материалы, и предоставлять различные методы для доступа к db путем предоставления запросов.

Ответ 6

Я бы не стал беспокоиться о создании новых операторов. Однако открытие соединения с базой данных может быть ресурсоемким, а открытие и закрытие соединений влияет на производительность.

Отключение связей в процессе самостоятельного управления обычно довольно плохо.

Вам следует использовать объединение пулов. Обычно вы отправляете закрытый коммандос, но вы только возвращаете это соединение в пул. Когда вы запрашиваете новое соединение, он будет повторно использовать соединение, которое вы дали ранее.

Возможно, вы захотите иметь разные инструкции для одного соединения. Заявление представляет собой реализацию и интерфейс. В зависимости от того, что вам нужно, вы иногда хотите использовать CallableStatment. Некоторая логика может быть повторно использована, когда требуется.