← Назад к вопросам

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

2.3 Middle🔥 171 комментариев
#Spring Framework#Базы данных и SQL

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

# JDBC vs JdbcTemplate

Краткое сравнение

Оба используются для работы с БД, но на разных уровнях абстракции:

АспектJDBCJdbcTemplate
УровеньLow-level APISpring wrapper
BoilerplateМного кодаМинимум кода
Resource managementРучноеАвтоматическое
Error handlingSQLExceptionDataAccessException
Версия JavaСтандартный с Java 1.1Spring 1.0+

JDBC (Java Database Connectivity)

Что это

JDBC это стандартный Java API для работы с реляционными БД через SQL:

public class UserDAO {
    
    public User getUserById(Long id) throws SQLException {
        Connection conn = null;
        PreparedStatement stmt = null;
        ResultSet rs = null;
        
        try {
            // 1. Получаем соединение
            conn = DriverManager.getConnection("jdbc:postgresql://localhost/db");
            
            // 2. Создаём prepared statement
            stmt = conn.prepareStatement("SELECT * FROM users WHERE id = ?");
            stmt.setLong(1, id);
            
            // 3. Выполняем запрос
            rs = stmt.executeQuery();
            
            // 4. Обрабатываем результат
            if (rs.next()) {
                User user = new User();
                user.setId(rs.getLong("id"));
                user.setName(rs.getString("name"));
                user.setEmail(rs.getString("email"));
                return user;
            }
        } finally {
            // 5. Закрываем ресурсы (очень важно!)
            if (rs != null) rs.close();
            if (stmt != null) stmt.close();
            if (conn != null) conn.close();
        }
        return null;
    }
}

Проблемы с JDBC

❌ Много boilerplate кода
❌ Ручное управление ресурсами (close())
❌ Легко забыть закрыть соединение (утечка)
❌ Скучное обработка exception (checked SQLException)
❌ Много try-catch блоков
❌ Сложность отличается между типами БД

Проверенный способ (Try-with-resources)

public User getUserById(Long id) throws SQLException {
    String sql = "SELECT * FROM users WHERE id = ?";
    
    try (Connection conn = DriverManager.getConnection(url);
         PreparedStatement stmt = conn.prepareStatement(sql)) {
        
        stmt.setLong(1, id);
        try (ResultSet rs = stmt.executeQuery()) {
            if (rs.next()) {
                return mapRowToUser(rs);
            }
        }
    }
    return null;
}

private User mapRowToUser(ResultSet rs) throws SQLException {
    User user = new User();
    user.setId(rs.getLong("id"));
    user.setName(rs.getString("name"));
    return user;
}

JdbcTemplate (Spring)

Что это

JdbcTemplate это Spring wrapper вокруг JDBC, который упрощает работу:

@Repository
public class UserDAOSpring {
    
    @Autowired
    private JdbcTemplate jdbcTemplate;
    
    public User getUserById(Long id) {
        String sql = "SELECT * FROM users WHERE id = ?";
        
        return jdbcTemplate.queryForObject(sql, 
            new Object[]{id},
            new UserRowMapper());
    }
}

private static class UserRowMapper implements RowMapper<User> {
    @Override
    public User mapRow(ResultSet rs, int rowNum) throws SQLException {
        User user = new User();
        user.setId(rs.getLong("id"));
        user.setName(rs.getString("name"));
        user.setEmail(rs.getString("email"));
        return user;
    }
}

Преимущества JdbcTemplate

✓ Минимум boilerplate
✓ Автоматическое управление ресурсами
✓ Unchecked exceptions (DataAccessException)
✓ Встроенное connection pooling
✓ Простой API для разных операций
✓ Интеграция с Spring TransactionManager

Сравнение кода

Получение одного объекта

JDBC:

Connection conn = DriverManager.getConnection(url);
PreparedStatement stmt = conn.prepareStatement(sql);
stmt.setLong(1, id);
ResultSet rs = stmt.executeQuery();
if (rs.next()) {
    user = mapRow(rs);
}
rs.close();
stmt.close();
conn.close();

JdbcTemplate:

User user = jdbcTemplate.queryForObject(sql, 
    new Object[]{id}, 
    new UserRowMapper());

Получение списка

JDBC:

List<User> users = new ArrayList<>();
try (Connection conn = DriverManager.getConnection(url);
     Statement stmt = conn.createStatement();
     ResultSet rs = stmt.executeQuery(sql)) {
    while (rs.next()) {
        users.add(mapRow(rs));
    }
}
return users;

JdbcTemplate:

return jdbcTemplate.query(sql, new UserRowMapper());

INSERT/UPDATE/DELETE

JDBC:

try (Connection conn = DriverManager.getConnection(url);
     PreparedStatement stmt = conn.prepareStatement(sql)) {
    stmt.setString(1, user.getName());
    stmt.setString(2, user.getEmail());
    int affected = stmt.executeUpdate();
    return affected > 0;
}

JdbcTemplate:

int affected = jdbcTemplate.update(sql, 
    user.getName(), 
    user.getEmail());
return affected > 0;

Обработка ошибок

JDBC:

try {
    // JDBC code
} catch (SQLException e) {  // checked exception
    logger.error("DB error", e);
    throw new RuntimeException(e);
}

JdbcTemplate:

try {
    // JdbcTemplate code
} catch (DataAccessException e) {  // unchecked exception
    // Spring автоматически конвертирует SQLException
    logger.error("DB error", e);
}

Когда использовать что

JDBC используй когда:

✓ Работаешь без Spring (чистый Java)
✓ Нужен полный контроль над соединением
✓ Очень нестандартные операции
✓ Legacy код требует классического подхода

JdbcTemplate используй когда:

✓ Работаешь в Spring приложении (обычный случай)
✓ Нужна быстрая разработка
✓ Стандартные CRUD операции
✓ Нужна простота и читаемость
✓ Хочешь меньше боди-plate

Альтернативы JdbcTemplate

В современных Spring приложениях есть варианты:

1. Spring Data JPA (лучше для ORM)

@Repository
public interface UserRepository extends JpaRepository<User, Long> {
    Optional<User> findById(Long id);
}

// Использование:
User user = userRepository.findById(1L).orElse(null);

2. Query DSL (типобезопасный)

QUser qUser = QUser.user;
User user = queryFactory
    .selectFrom(qUser)
    .where(qUser.id.eq(1L))
    .fetchOne();

3. JDBI (лучше чем JdbcTemplate)

@RegisterBeanMapper(User.class)
public interface UserDao {
    @SqlQuery("SELECT * FROM users WHERE id = :id")
    User findById(@Bind("id") Long id);
}

Практическая рекомендация

Для modern Java приложений порядок предпочтения:

1. Spring Data JPA (если нужна ORM) ← используй это
2. JdbcTemplate (если нужен control + простота)
3. JDBC (если без Spring)
4. Query DSL/JDBI (специальные случаи)

Вывод

КритерийJDBCJdbcTemplate
BoilerplateМногоМинимум
Resource mgmtРучноеАвтоматическое
Error handlingSQLExceptionDataAccessException
Spring integrationНетПолная
ComplexityВысокаяНизкая
Use caseLegacy / no SpringSpring приложения

Совет: В Spring приложениях всегда используй JdbcTemplate (или JPA), а JDBC оставь для non-Spring проектов.

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