PreparedStatement
PreparedStatement — безопасная и более быстрая версия Statement, где параметры запроса передаются отдельно от текста SQL, а не вклеиваются в строку.
String sql = "SELECT * FROM users WHERE email = ? AND age > ?";
PreparedStatement stmt = conn.prepareStatement(sql);
stmt.setString(1, "artur@mail.ru"); // первый ? — индексация с 1, не с 0!
stmt.setInt(2, 18);
ResultSet rs = stmt.executeQuery();
? — место, куда подставится значение. Главная причина использовать PreparedStatement вместо обычного Statement — защита от SQL-инъекций (подробный разбор — в теме «SQL-инъекции и защита»).
Копнуть глубже
PreparedStatement также быстрее при повторных вызовах. База компилирует план выполнения запроса один раз и переиспользует его при следующих вызовах с другими параметрами — не нужно заново разбирать структуру SQL-текста на каждый вызов, как с обычным Statement.
Для INSERT/UPDATE/DELETE используется executeUpdate(), а не executeQuery() (тот — только для SELECT):
PreparedStatement stmt = conn.prepareStatement("UPDATE users SET age = ? WHERE id = ?");
stmt.setInt(1, 26);
stmt.setInt(2, 1);
int rowsAffected = stmt.executeUpdate(); // вернёт, сколько строк изменилось
Batch — пакетная вставка для большого количества записей сразу, гораздо быстрее, чем по одной:
PreparedStatement stmt = conn.prepareStatement("INSERT INTO users (name) VALUES (?)");
for (String name : names) {
stmt.setString(1, name);
stmt.addBatch(); // добавить в пакет, не выполнять сразу
}
stmt.executeBatch(); // выполнить весь пакет одним обращением к базе
• зачем нужен batch и почему он быстрее одиночных вставок (если дошёл до 2-го слоя).