В чем разница между JDBC и JdbcTemplate в Spring?

Ответ

JDBC (Java Database Connectivity) — низкоуровневый стандартный API Java для работы с реляционными базами данных. Требует ручного управления ресурсами и обработки исключений.

// Шаблонный (boilerplate) код на чистом JDBC
Connection conn = null;
PreparedStatement stmt = null;
ResultSet rs = null;
try {
    conn = DriverManager.getConnection(url, user, pass);
    stmt = conn.prepareStatement("SELECT * FROM user WHERE id = ?");
    stmt.setInt(1, userId);
    rs = stmt.executeQuery();
    // Обработка ResultSet
} catch (SQLException e) {
    // Обработка исключения
} finally {
    // Обязательное закрытие ресурсов в обратном порядке
    if (rs != null) try { rs.close(); } catch (SQLException e) { /* log */ }
    if (stmt != null) try { stmt.close(); } catch (SQLException e) { /* log */ }
    if (conn != null) try { conn.close(); } catch (SQLException e) { /* log */ }
}

JdbcTemplate — ключевой класс Spring Framework (модуль spring-jdbc), который абстрагирует и упрощает работу с JDBC, устраняя шаблонный код.

Основные преимущества JdbcTemplate:

  1. Управление ресурсами: Автоматически получает, использует и закрывает соединения (Connection), операторы (Statement) и наборы результатов (ResultSet).
  2. Преобразование исключений: Перевод проверяемых SQLException в непроверяемые исключения из иерархии DataAccessException, что делает код чище.
  3. Удобные методы: Предоставляет множество перегруженных методов для запросов и обновлений.
    // Эквивалентная операция с JdbcTemplate
    String sql = "SELECT * FROM user WHERE id = ?";
    User user = jdbcTemplate.queryForObject(sql,
    (rs, rowNum) -> new User(rs.getInt("id"), rs.getString("name")), // RowMapper
    userId);
  4. Интеграция: Прозрачно работает с механизмом транзакций Spring.

Итог: JdbcTemplate — это высокоуровневая абстракция над JDBC, которая следует шаблону Template Method, беря на себя рутинные задачи и позволяя разработчику сосредоточиться на бизнес-логике (SQL и обработке результатов).

Ответ 18+ 🔞

Ну вот смотри, как это обычно бывает. Сидишь ты такой, пишешь на Java, и тебе надо к базе данных приконнектиться. Берёшь JDBC, этот старый добрый стандарт, и начинается пиздец, прости господи.

Прям как в том анекдоте: "Муму! Муму!" — а он нихуя не говорит, только мычит. Так и тут. Хочешь просто данные получить, а тебе надо вот эту всю ебучую церемонию отыграть: Connection, Statement, ResultSet, try-catch-finally, закрыть всё в правильном порядке, а если забудешь — утечка соединений, блядь, и приложение накрывается медным тазом.

Смотри, какой хуйни код требует чистый JDBC:

Connection conn = null;
PreparedStatement stmt = null;
ResultSet rs = null;
try {
    conn = DriverManager.getConnection(url, user, pass);
    stmt = conn.prepareStatement("SELECT * FROM user WHERE id = ?");
    stmt.setInt(1, userId);
    rs = stmt.executeQuery();
    // Обработка ResultSet
} catch (SQLException e) {
    // Обработка исключения
} finally {
    // Обязательное закрытие ресурсов в обратном порядке
    if (rs != null) try { rs.close(); } catch (SQLException e) { /* log */ }
    if (stmt != null) try { stmt.close(); } catch (SQLException e) { /* log */ }
    if (conn != null) try { conn.close(); } catch (SQLException e) { /* log */ }
}

Ёпта, ядрёна вошь! Я просто пользователя найти хочу, а у меня тут целая опера по освобождению ресурсов разворачивается. Чувствуешь, какой овердохуища шаблонного кода? Это ж Герасим бы и тот охренел.

А теперь, внимание, появляется JdbcTemplate из Spring. Это как если бы к немому Герасиму приставили переводчика, который всё за него делает. И он такой: "Му-му? А, понял, ща сделаем."

И вся эта хуйня с ручным управлением — нахуй не нужна. JdbcTemplate сам всё закроет, сам исключения переведёт из этих проверяемых SQLException в нормальные, непроверяемые DataAccessException. Не надо больше в каждом методе этот цирк с finally разводить.

Смотри, как та же самая операция выглядит теперь:

String sql = "SELECT * FROM user WHERE id = ?";
User user = jdbcTemplate.queryForObject(sql,
    (rs, rowNum) -> new User(rs.getInt("id"), rs.getString("name")), // RowMapper
    userId);

Один хуй, в рот меня чих-пых! Всё. Никаких try-catch, никакого ручного закрытия. Написал SQL, сказал, как результат в объект превращать, и пошёл пить чай.

Короче, преимущества JdbcTemplate, если по пунктам:

  1. Ресурсами сам рулит. Как тот самый здоровый татарин-немой — молчит, но делает. Сам откроет, сам закроет, не проебётся.
  2. Исключения преобразует. Больше не надо в каждом втором методе throws SQLException писать или ловить. Spring их в свои DataAccessException завернёт — чище код, меньше головной боли.
  3. Куча удобных методов. query, queryForObject, update, execute — бери и пользуйся, не изобретай велосипед.
  4. В транзакции Spring'а вписывается. Это вообще отдельная песня, потом оценишь.

Итог-то какой? JdbcTemplate — это высшая лига после этого JDBC-детсада. Он по шаблону Template Method работает: всю рутину берёт на себя, а тебе оставляет только суть — SQL написать и результат обработать. Как будто тебе дали не лопату, а экскаватор. Эффективность — пиздец.