본문으로 건너뛰기
Advertisement

9.3 JdbcTemplate 및 대용량 배치 처리 기초

ORM(JPA) 시대가 도래했어도 전통적인 RDBMS 지향 접근이나 수백만 건의 대량 배치(Batch) Insert 처리에는 JdbcTemplate이 압도적으로 빠르고 확실한 성능을 자랑합니다.

1. JdbcTemplate의 기본 구조

JdbcTemplate은 JDBC의 복잡한 커넥션 확보, Statement 생성, 자원 해제(try-catch-finally)를 스프링 프레임워크가 대신 템플릿 콜백 패턴으로 처리해 주는 유틸리티 클래스입니다.

@Repository
@RequiredArgsConstructor
public class UserRepositoryJdbc {

private final JdbcTemplate jdbcTemplate;

// 1. 단건 조회 (QueryForObject)
public User findById(Long id) {
String sql = "SELECT * FROM users WHERE id = ?";
return jdbcTemplate.queryForObject(sql, userRowMapper(), id);
}

// 2. 다건 조회 (Query)
public List<User> findAll() {
String sql = "SELECT * FROM users";
return jdbcTemplate.query(sql, userRowMapper());
}

// 3. 삽입/수정/삭제 (Update)
public int updateName(Long id, String newName) {
String sql = "UPDATE users SET name = ? WHERE id = ?";
return jdbcTemplate.update(sql, newName, id);
}

// 데이터베이스 결과를 자바 객체로 매핑하는 RowMapper 설정
private RowMapper<User> userRowMapper() {
return (rs, rowNum) -> {
User user = new User();
user.setId(rs.getLong("id"));
user.setName(rs.getString("name"));
return user;
};
}
}

2. batchUpdate를 이용한 고속 벌크 연산

JPA의 영속성 컨텍스트는 수만 건의 데이터를 엑셀에서 읽어 1건씩 Insert할 때 병목(Out of Memory나 성능 지연)이 매우 큽니다. 반면 JdbcTemplatebatchUpdate를 활용하면 데이터베이스의 Bulk 연산 기능을 끌어내 100배 이상의 성능 향상을 얻을 수 있습니다.

@Repository
@RequiredArgsConstructor
public class BulkUserRepository {

private final JdbcTemplate jdbcTemplate;

@Transactional
public void saveAllBatch(List<User> userList) {
String sql = "INSERT INTO users (name, age) VALUES (?, ?)";

// 1000건 단위로 청크(Chunk)를 나누어 DB로 전송
jdbcTemplate.batchUpdate(sql, userList, 1000,
(PreparedStatement ps, User user) -> {
ps.setString(1, user.getName());
ps.setInt(2, user.getAge());
}
);
}
}

대용량 데이터를 다룰 때 application.yml (또는 DB 접속 URL)에 반드시 rewriteBatchedStatements=true (MySQL/MariaDB 기준) 옵션을 켜야 진정한 의미의 속도 향상(Bulk Insert)이 이루어집니다. 이 옵션이 없으면 batchUpdate를 써도 네트워크를 1건씩 통신합니다.

Advertisement