20만 건의 데이터를 읽어와 데이터베이스에 저장하는 로직을 구현하면서, JPA의 saveAll()
방식과 JDBC를 활용한 Bulk Insert
방식을 비교하며 겪었던 차이를 중심으로 작성한 글이다.
대량 데이터 저장 기능은 시스템 성능에 직접적인 영향을 미치기 때문에, 효율적인 쿼리 실행 방식이 필수적이다. 성능 최적화를 목표로 두 가지 방식의 장단점을 분석하고, 그 차이를 정리했다.
JDBC 위에 얇은 추상화 계층을 제공, SQL 직접 제어가 가능.
설정이 간단하며 성능 최적화가 중요한 애플리케이션에 적합.
개발자가 SQL을 직접 작성하여 데이터베이스 작업을 세밀하게 제어 가능.
@Repository
public class MyRepository {
@Autowired
private JdbcTemplate jdbcTemplate;
public List<MyEntity> findAll() {
return jdbcTemplate.query("SELECT * FROM my_table", new BeanPropertyRowMapper<>(MyEntity.class));
}
}
💡 JDBC는 Java에서 데이터베이스와 상호작용하기 위한 표준 API입니다. 이를 통해 Java 애플리케이션은 다양한 관계형 데이터베이스에서 데이터를 읽고 쓰는 작업을 수행할 수 있습니다.
@Entity
public class MyEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
}
public interface MyRepository extends JpaRepository<MyEntity, Long> {
}
saveAll()
은 편리하게 다수의 엔터티를 저장할 수 있는 메서드batchUpdate
를 활용하면 대량의 데이터를 효율적으로 삽입할 수 있음@Repository
@RequiredArgsConstructor
public class PostCustomRepositoryImpl implements PostCustomRepository {
private final JdbcTemplate jdbcTemplate;
// 게시글 목록 저장, BULK INSERT 방식으로 처리
@Transactional
public void saveAllByJdbcTemplate(List<Post> posts) {
String sql = "INSERT INTO post (title, content, name, views) VALUES (?, ?, ?, ?)";
jdbcTemplate.batchUpdate(sql, posts, 1000, (ps, post) -> {
ps.setString(1, post.getTitle());
ps.setString(2, post.getContent());
ps.setString(3, post.getName());
ps.setLong(4, post.getViews());
});
}
}