2022. 11. 19. 02:52ㆍTIL
1. Spring 수업을 들었다.
오늘은 스프링과 스프링 부트의 차이, AutoConfiguration을 학습했다.
스프링을 배우면 스프링 부트가 얼마나 편하고 다양한 기능을 제공하는지 깨닫게 된다.
2. Spring 과제 제출
지난 주 1차 과제를 제출했고, 주말 사이에 코드 리뷰 받은 부분들을 개선했다.
그리고 이번 주는 새로운 2차 과제를 시작했고, 어제 마무리지었다.
그동안 TIL 작성이 뜸했는데 좀 바빴던 것 같다.
파일과 메모리에서 관리하던 데이터를 DB에 저장, 조회하는 작업으로 변경하는 것이었고
데이터 접근 기술로는 JDBC를 사용해야 했다.
RowMapper를 이용해서 레코드 한 줄씩 Java 객체에 매핑해야 했는데,
고객 1명이 바우처 N개를 들고 있는 1:N의 상황에서
고객과 바우처 테이블을 조인하면 row 수가 4건으로 늘어난다.
나는 고객 클래스에 바우처를 아래 코드처럼 리스트로 관리하고 있는데
class Customer{
private List<Voucher> wallet;
...
public void makeWallet(List<Voucher> wallet){
this.wallet = wallet;
}
}
RowMapper로는 Customer 객체를 한 번 생성하면서 Voucher를 해당 객체에게 어떻게 담아야 할까..? 고민하고 있었다.
그러다가 내린 결론은
일단 Customer을 조회하고, 쿼리를 한 방 더 날려서 해당 고객의 Voucher 목록을 가져온 뒤에, makeWallet() 메소드를 통해 넣어주어야 겠다고 생각했었다.
아무리봐도 코드가 지저분해서 맘이 편치 않던 상황에서
팀원 분이 먼저 오셔서 어려우신 점 없냐고 물어봐주셨고 이 부분을 말씀드렸다.
그러더니 바로 ResultSetExtractor를 소개해주시면서 링크를 하나 주셨다.
내 코드에 적용해서 Customer 객체를 1회 생성하고 row 수 만큼 Voucher를 List<Voucher>에 담을 수 있게되었다.
public class CustomerResultSetExtractor implements ResultSetExtractor<Customer> {
private final CustomerRowMapper customerRowMapper;
private final VoucherRowMapper voucherRowMapper;
public CustomerResultSetExtractor(CustomerRowMapper customerRowMapper, VoucherRowMapper voucherRowMapper) {
this.customerRowMapper = customerRowMapper;
this.voucherRowMapper = voucherRowMapper;
}
@Override
public Customer extractData(ResultSet rs) throws SQLException, DataAccessException {
Customer customer = null;
int row = 0;
while (rs.next()) {
// Customer 최초 1회 생성
if (customer == null) {
customer = customerRowMapper.mapRow(rs, row);
}
//바우처가 없는 회원이라면 즉시 리턴
if (rs.getBytes("voucher_id") == null) {
return customer;
}
Voucher voucher = voucherRowMapper.mapRow(rs, row);
customer.getWallet().add(voucher);
row++;
}
return customer;
}
}
Shout out to DevYSK