2024. 5. 17. 09:53ㆍBack-End/Spring
데이터베이스와의 상호작용에서 결과 집합(Result Set)을 처리하는 일은 매우 중요하다. 스프링 프레임워크는 JDBC를 통해 데이터베이스와 쉽게 상호작용할 수 있도록 다양한 유틸리티 클래스를 제공하며, 그 중 ResultSetExtractor는 복잡한 쿼리 결과를 처리할 때 유용한 도구이다. 이번 글에서는 ResultSetExtractor에 대해 알아보고, 이를 사용하는 방법을 예제와 함께 설명하고자 한다.
ResultSetExtractor란?
ResultSetExtractor는 스프링 JDBC 모듈에서 제공하는 인터페이스로, JDBC ResultSet을 커스터마이즈드 방식으로 처리할 수 있게 한다. 이 인터페이스는 단일 메서드인 extractData를 포함하며, 이 메서드를 구현하여 결과 집합을 원하는 형태로 변환할 수 있다.
왜 ResultSetExtractor를 사용하는가?
ResultSetExtractor는 복잡한 결과 집합을 처리하는 데 적합하다. 단순한 쿼리의 경우 RowMapper를 사용하여 각 행을 매핑할 수 있지만, 복잡한 조인 쿼리나 계층적 데이터를 처리할 때는 ResultSetExtractor가 더 적합하다. 예를 들어, 여러 테이블을 조인한 결과를 객체 그래프로 변환하거나, 중첩된 데이터를 처리해야 할 때 유용하다.
사용 방법
ResultSetExtractor를 사용하는 방법은 간단하다. 먼저, ResultSetExtractor 인터페이스를 구현하는 클래스를 정의한 후, JdbcTemplate의 query 메서드에 이를 전달하여 사용한다.
예제 코드
다음은 ResultSetExtractor를 사용하여 데이터베이스에서 복잡한 쿼리 결과를 처리하는 예제이다.
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.ResultSetExtractor;
import org.springframework.stereotype.Repository;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
@Repository
public class UserRepository {
private final JdbcTemplate jdbcTemplate;
@Autowired
public UserRepository(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
public List<User> findAllUsersWithOrders() {
String sql = "SELECT u.id AS user_id, u.name AS user_name, o.id AS order_id, o.amount AS order_amount " +
"FROM users u LEFT JOIN orders o ON u.id = o.user_id";
return jdbcTemplate.query(sql, new UserWithOrdersExtractor());
}
private static class UserWithOrdersExtractor implements ResultSetExtractor<List<User>> {
@Override
public List<User> extractData(ResultSet rs) throws SQLException {
Map<Long, User> userMap = new HashMap<>();
while (rs.next()) {
Long userId = rs.getLong("user_id");
User user = userMap.get(userId);
if (user == null) {
user = new User();
user.setId(userId);
user.setName(rs.getString("user_name"));
user.setOrders(new ArrayList<>());
userMap.put(userId, user);
}
Long orderId = rs.getLong("order_id");
if (orderId != null) {
Order order = new Order();
order.setId(orderId);
order.setAmount(rs.getDouble("order_amount"));
user.getOrders().add(order);
}
}
return new ArrayList<>(userMap.values());
}
}
}
코드 설명
- UserRepository 클래스:
- UserRepository는 JdbcTemplate을 사용하여 데이터베이스와 상호작용하는 리포지토리 클래스이다.
- findAllUsersWithOrders 메서드는 사용자와 그들의 주문을 조회하는 쿼리를 실행하고, 결과를 User 객체의 리스트로 변환한다. - UserWithOrdersExtractor 클래스:
- UserWithOrdersExtractor는 ResultSetExtractor 인터페이스를 구현하여, ResultSet을 사용자와 주문 객체로 변환한다.
- extractData 메서드는 결과 집합을 처리하여 사용자와 주문 객체를 매핑한다.
- 사용자 ID를 키로 하는 맵을 사용하여, 중복된 사용자 객체를 생성하지 않고 각 사용자의 주문 목록을 업데이트한다.
결론
ResultSetExtractor는 스프링 JDBC에서 복잡한 결과 집합을 처리하는 데 매우 유용한 도구이다. 이를 사용하면 복잡한 쿼리 결과를 커스터마이즈된 객체 그래프로 변환할 수 있다. RowMapper가 단순한 행 매핑에 적합하다면, ResultSetExtractor는 다중 행 및 중첩된 데이터 구조를 처리하는 데 강력한 해결책을 제공한다. 스프링 애플리케이션에서 복잡한 데이터 매핑이 필요할 때, ResultSetExtractor를 적극 활용해 보기를 권장한다.
'Back-End > Spring' 카테고리의 다른 글
Spring MVC (0) | 2024.05.18 |
---|---|
AOP (Aspect-Oriented Programming) (0) | 2024.05.18 |
@Transactional과 TransactionTemplate (0) | 2024.05.17 |
배치 업데이트(Batch Update) (0) | 2024.05.17 |
Spring Data JDBC (0) | 2024.05.16 |