В чем разница между методами execute, executeQuery и executeUpdate в JDBC?

Ответ

Эти методы интерфейса Statement служат для выполнения SQL-запросов, но предназначены для разных типов операций.

  • executeQuery(String sql)

    • Назначение: Выполняет только запросы на чтение данных — оператор SELECT.
    • Возвращаемое значение: Объект ResultSet, содержащий результаты запроса.
    • Использование: Когда нужно получить данные из базы.
      ResultSet rs = statement.executeQuery("SELECT * FROM users");
  • executeUpdate(String sql)

    • Назначение: Выполняет запросы, изменяющие данные или схему БД: INSERT, UPDATE, DELETE, а также DDL-операторы (CREATE, ALTER, DROP).
    • Возвращаемое значение: int — количество затронутых строк (для DDL возвращает 0).
    • Использование: Для модификации данных или структуры таблиц.
      int rows = statement.executeUpdate("DELETE FROM logs WHERE date < '2024-01-01'");
      System.out.println("Удалено строк: " + rows);
  • execute(String sql)

    • Назначение: Универсальный метод для выполнения любых SQL-запросов.
    • Возвращаемое значение: boolean. Возвращает true, если первый результат является ResultSet (т.е. был выполнен SELECT), и false если это счетчик обновлений или результат отсутствует.
    • Использование: Полезен, когда тип запроса неизвестен заранее (например, в динамических конструкторах запросов). После вызова execute() для получения результата нужно использовать getResultSet() или getUpdateCount().
      boolean hasResultSet = statement.execute(someDynamicSql);
      if (hasResultSet) {
      ResultSet rs = statement.getResultSet();
      // обработка результатов SELECT
      } else {
      int updateCount = statement.getUpdateCount();
      // обработка результата UPDATE/INSERT/DELETE
      }

Рекомендация: Для явных операций всегда используйте executeQuery (для SELECT) или executeUpdate (для INSERT/UPDATE/DELETE). Метод execute оставьте для сценариев, где запрос формируется динамически.

Ответ 18+ 🔞

Так, слушай, а вот эти три метода из Statement — они же, блядь, как три брата-хулигана, каждый со своей специализацией, но все из одной песочницы. Один за чтение, другой за запись, а третий — универсальный солдат, который нихуя не понятно, что принесёт, пока не откроешь коробку.

Смотри, разбираем по косточкам, а то запутаться — хуй с горы.

Первый, executeQuery(String sql) — это наш книжный червь, интеллигент. Его задача — только читать, нихуя не трогая. Кидаешь ему SELECT, а он тебе в ответ — ResultSet, эту пачку данных, как стопку бумажек из архива.

ResultSet rs = statement.executeQuery("SELECT * FROM users");

Попробуй ему INSERT сунуть — он тебе SQLException в ебало бросит, типа «я не для этого, мудак!». Используй, когда просто достать надо.

Второй, executeUpdate(String sql) — это грузчик, работяга. Его стихия — менять всё вокруг: INSERT, UPDATE, DELETE, да хоть таблицу новую создать (CREATE TABLE). Он не болтает, он делает. Возвращает тебе циферку — сколько строк пострадало от его деятельности.

int rows = statement.executeUpdate("DELETE FROM logs WHERE date < '2024-01-01'");
System.out.println("Удалено строк: " + rows);

Сделал дело — получи цифру. Для DDL-команд (CREATE, ALTER) он вернёт ноль, но работу сделает. Используй, когда нужно что-то изменить.

А третий, execute(String sql) — это, блядь, кот в мешке, шкатулка с сюрпризом. Он универсальный, ему похуй, что выполнять: SELECT, UPDATE — всё схавает. Но вот возвращает он не результат, а булеву загадку. true — если первый результат это ResultSet (значит, был SELECT). false — если это счётчик обновлений или нихуя.

boolean hasResultSet = statement.execute(someDynamicSql);
if (hasResultSet) {
    ResultSet rs = statement.getResultSet(); // Ага, значит SELECT был!
    // ...обрабатываешь данные
} else {
    int updateCount = statement.getUpdateCount(); // А, значит что-то меняли!
    // ...смотришь, сколько строк зацепили
}

Вот в чём, блядь, фишка: после него надо ещё доп. методы дергать, чтобы понять, что там произошло. Удобно, только если запрос у тебя формируется на лету, и ты заранее нихуя не знаешь, что прилетит.

Итог, ёпта:

  • Читаешь (SELECT) — executeQuery(). Точно, без сюрпризов.
  • Пишешь/Меняешь (INSERT/UPDATE/DELETE/DDL) — executeUpdate(). Просто и понятно.
  • А если у тебя запрос, как погода в мае — нихуя не ясно, что будет — вот тогда execute(). Но будь готов к дополнительным телодвижениям.

Не усложняй, блядь, там, где не надо. Если знаешь, что делаешь — используй узкоспециализированного мудака. Универсальный — он на то и универсальный, чтобы в нём можно было и запутаться, и нихуя не понять.