Что делает метод execute() у объектов Statement и ExecutorService в Java?

«Что делает метод execute() у объектов Statement и ExecutorService в Java?» — вопрос из категории Базы данных, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Метод execute() имеет разную семантику в контексте JDBC (Statement) и многопоточности (ExecutorService).

1. Statement.execute(String sql) (JDBC)

Отправляет произвольный SQL-запрос в базу данных. Полезен, когда тип запроса (SELECT или DML) неизвестен заранее.

Поведение и возвращаемое значение:

  • Возвращает boolean: true, если запрос вернул ResultSet (обычно SELECT). false, если запрос вернул счётчик обновлённых строк (INSERT, UPDATE, DELETE, DDL) или ничего.
  • Для получения ResultSet нужно вызвать getResultSet(). Для получения счётчика обновлений — getUpdateCount().

Пример:

Statement stmt = connection.createStatement();
String dynamicSql = "SELECT * FROM users WHERE active = true";

boolean hasResults = stmt.execute(dynamicSql); // Возвращает true

if (hasResults) {
    try (ResultSet rs = stmt.getResultSet()) {
        while (rs.next()) {
            System.out.println(rs.getString("username"));
        }
    }
}

Когда использовать: Для динамического SQL. Для известных типов запросов предпочтительнее executeQuery() (SELECT) или executeUpdate() (DML).

2. ExecutorService.execute(Runnable command)

Асинхронно выполняет задачу (Runnable) в одном из потоков пула. Не возвращает результат задачи.

Поведение:

  • Задача ставится в очередь. Свободный поток из пула извлекает и выполняет её.
  • Метод возвращает void. Для получения результата или статуса используйте submit(Callable/Runnable), который возвращает Future.
  • Может выбросить RejectedExecutionException, если пул закрыт или очередь переполнена.

Пример:

ExecutorService executor = Executors.newFixedThreadPool(2);

Runnable task = () -> {
    System.out.println("Task executed by " + Thread.currentThread().getName());
};
executor.execute(task); // Задача будет выполнена в фоновом потоке пула

Ключевое отличие: Statement.execute() — синхронная операция работы с БД, ExecutorService.execute() — асинхронная операция для управления потоками.