본문 바로가기
spring

[Spring] JdbcTemplate과 일반 JDBC 코드의 차이점

by goblin- 2024. 11. 19.

 

1. JdbcTemplate vs 일반 JDBC 코드

특성 JdbcTemplate 일반 JDBC 코드
코드 간결성 반복 작업(연결, 자원 해제, 예외 처리)을 자동화하여 코드가 간결함. 연결, 자원 해제, 예외 처리를 수동으로 작성해야 함.
리소스 관리 자원을 자동으로 닫아줌 Connection, Statement, ResultSet을 명시적으로
닫아야함
예외 처리 SQLException을 Spring의 DataAccessException으로 변환하여 처리. SQL및 JDBC 관련 예외를 세분화하여 직접 처리해야 함.
예외 추상화 데이터베이스독립적 예외 처리를 제공. 벤더에 따라 다른 SQLState 및 에러 코드를 수동으로 처리해야 함.
코드 유지보수 코드가 간결하고 반복 작업이 제거되어 유지보수가 쉬움 반복 코드가 많아 가독성이 낮고 유지보수 비용이 증가.
트랜잭션 관리 Spring의 선언적 트랜잭션 관리와 쉽게 통합 가능. 트랜잭션을 직접 관리해야 함.
배치 처리 지원 batchupdate를 사용하여 간단히 구현 가능. 배치 처리 구현이 복잡하고 반복적인 코드가 필요.
객체 매핑 RowMapper를 통해 객체로 결과를 매핑. 데이터 매핑을 수동으로 구현해야 함.
Spring과의 통합 Spring DI 및 Bean 관리와 완벽히 통합. Spring과의 통합이 어려움.

 

 

2. 주요 차이점 코드 예제

 

1) 리소스 관리

 

JdbcTemplate:

String query = "SELECT * FROM employees";
List<Employee> employees = jdbcTemplate.query(query, (rs, rowNum) ->
        new Employee(rs.getInt("id"), rs.getString("name"), rs.getString("position"))
);

 

일반 JDBC:

List<Employee> employees = new ArrayList<>();
try (Connection connection = DriverManager.getConnection(jdbcUrl, username, password);
     Statement statement = connection.createStatement();
     ResultSet resultSet = statement.executeQuery("SELECT * FROM employees")) {

    while (resultSet.next()) {
        employees.add(new Employee(
                resultSet.getInt("id"),
                resultSet.getString("name"),
                resultSet.getString("position")
        ));
    }

} catch (SQLException e) {
    e.printStackTrace();
}

 

 

2) 예외 처리

 

JdbcTemplate:

 

예외를 Spring의 DataAccessException으로 변환하여 처리.

데이터베이스 독립적인 예외 처리 가능.

try {
    jdbcTemplate.update("INSERT INTO employees (name, position) VALUES (?, ?)", "Alice", "Developer");
} catch (DataAccessException e) {
    System.err.println("Error: " + e.getMessage());
}

 

일반 JDBC:

 

SQLException을 처리해야 하며, 데이터베이스별 예외 처리가 필요.

try (Connection connection = DriverManager.getConnection(jdbcUrl, username, password);
     PreparedStatement preparedStatement = connection.prepareStatement("INSERT INTO employees (name, position) VALUES (?, ?)")) {

    preparedStatement.setString(1, "Alice");
    preparedStatement.setString(2, "Developer");
    preparedStatement.executeUpdate();

} catch (SQLException e) {
    System.err.println("SQL Error: " + e.getMessage());
    System.err.println("SQL State: " + e.getSQLState());
    System.err.println("Error Code: " + e.getErrorCode());
}

 

3) 트랜잭션 관리

 

JdbcTemplate:

 

Spring의 트랜잭션 관리 기능(@Transactional)과 쉽게 통합.

@Service
@Transactional
public class EmployeeService {
    private final JdbcTemplate jdbcTemplate;

    public EmployeeService(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    public void saveEmployee(String name, String position) {
        jdbcTemplate.update("INSERT INTO employees (name, position) VALUES (?, ?)", name, position);
    }
}

 

일반 JDBC:

 

트랜잭션을 직접 관리해야 하며 코드가 장황해짐.

try (Connection connection = DriverManager.getConnection(jdbcUrl, username, password)) {
    connection.setAutoCommit(false);

    try (PreparedStatement preparedStatement = connection.prepareStatement("INSERT INTO employees (name, position) VALUES (?, ?)")) {
        preparedStatement.setString(1, "Alice");
        preparedStatement.setString(2, "Developer");
        preparedStatement.executeUpdate();
        connection.commit();
    } catch (SQLException e) {
        connection.rollback();
        throw e;
    }

} catch (SQLException e) {
    e.printStackTrace();
}

 

4) 배치 처리

 

JdbcTemplate:

 

간단한 API로 대량 데이터 처리.

String sql = "INSERT INTO employees (name, position) VALUES (?, ?)";
jdbcTemplate.batchUpdate(sql, List.of(
        new Object[]{"Alice", "Developer"},
        new Object[]{"Bob", "Manager"},
        new Object[]{"Charlie", "Designer"}
));

 

일반 JDBC:

 

반복적인 코드를 작성해야 함.

String sql = "INSERT INTO employees (name, position) VALUES (?, ?)";
try (Connection connection = DriverManager.getConnection(jdbcUrl, username, password);
     PreparedStatement preparedStatement = connection.prepareStatement(sql)) {

    connection.setAutoCommit(false);

    preparedStatement.setString(1, "Alice");
    preparedStatement.setString(2, "Developer");
    preparedStatement.addBatch();

    preparedStatement.setString(1, "Bob");
    preparedStatement.setString(2, "Manager");
    preparedStatement.addBatch();

    preparedStatement.setString(1, "Charlie");
    preparedStatement.setString(2, "Designer");
    preparedStatement.addBatch();

    preparedStatement.executeBatch();
    connection.commit();

} catch (SQLException e) {
    e.printStackTrace();
}

 

3. JdbcTemplate의 주요 장점 요약

 

1. 리소스 관리 자동화:

Connection, Statement, ResultSet의 수동 닫기 작업 제거.

2. 예외 추상화:

Spring의 DataAccessException으로 데이터베이스 독립적인 예외 처리.

3. 간결한 코드:

SQL 실행과 결과 처리를 간단한 메서드 호출로 처리.

4. Spring 통합:

Spring DI와 트랜잭션 관리(@Transactional)와 완벽하게 통합.

5. 객체 매핑 지원:

RowMapper를 사용해 결과를 객체로 매핑.

 

4. 결론

 

JdbcTemplate은 일반 JDBC 코드보다 간결하고, 예외 처리와 리소스 관리가 자동화되어 생산성을 높입니다.

간단한 CRUD 작업에 적합하며, Spring의 다른 기능과 통합이 용이합니다.

대규모 프로젝트에서는 복잡한 객체 매핑이나 동적 SQL 생성이 필요한 경우, JPA나 MyBatis와 병행하여 사용하기도 합니다.