본문 바로가기

개발일지(일간)

04월 23일 변경사항

1. 예약 일별조회 api작성

  1. 일별조회 쿼리 추가

2. Builder사용하는 생성자 변경


1. 예약 일별조회 api작성


@GetMapping("{year}/{month}/{day}/{storeId}")
  public ResponseEntity<List<ReservationDayInfoResponseDto>> showReservations(@PathVariable Long storeId,@PathVariable Integer year,@PathVariable Integer month,@PathVariable Integer day) {
    List<ReservationDayInfoResponseDto> dtoList = reservationService.showReservations(storeId, year, month, day);
    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(new MediaType("application", "json", StandardCharsets.UTF_8));
    return RespoensEntity.ok().headers(headers).body(dtoList);
  }

날짜 정보를 @RequestParam을 사용하여 받을까 하다가, @PathVariable을 사용하여 받아도 문제가 없을 것 같아 일단 

@PathVariable을 사용하여 받도록 하였습니다.

 

1. 일별조회 쿼리 추가

기존 코드

Store store = storeService.findStoreByStoreId(storeId);
    ReservationMonthInfo reservationMonthInfo = findReservationMonthInfoByYearInfoAndMonthInfoAndStoreId(year,month,store);
    List<ReservationDayInfo> reservationDayInfoList =findAllByReservationMonthInfoAndDayInfo(reservationMonthInfo,day);

   return reservationDayInfoList.stream()
       .map(reservationDayInfo -> new ReservationDayInfoResponseDto(
           reservationDayInfo.getId(),
           reservationDayInfo.getDayInfo(),
           reservationDayInfo.getTimeInfo(),
           reservationDayInfo.getIsAvailable(),
           reservationDayInfo.getCapacity()
       ))
       .collect(Collectors.toList());

기존 코드에서는 store을 찾아온 후 monthInfo 조회, monthInfo의 id를 통해 dayInfo의 데이터를 가져온 후, map 이나 for문을 통해 dtoList로 만들어 반환을 하는 형태였습니다. 정리하자면,

store조회 -> monthInfo조회 -> dayInfo조회 -> map후 반환 의 형태였는데,

이런 형태면 간단한 일별 예약 조회 요청에 쿼리를 세번 날려야 해서 queryDSL을 통해 한번의 조회후 반환하도록 변경했습니다.

 

queryDSL코드

 @Override
  public List<ReservationDayInfoResponseDto> findReservationInfos(Long storeId, Integer year,
      Integer month, Integer day) {
    return jpaQueryFactory.select(
        Projections.bean(
            ReservationDayInfoResponseDto.class,
            reservationDayInfo.id,
            reservationDayInfo.dayInfo,
            reservationDayInfo.timeInfo,
            reservationDayInfo.isAvailable,
            reservationDayInfo.capacity
        )
    ).from(reservationMonthInfo)
        .leftJoin(reservationMonthInfo.reservationDayInfo, reservationDayInfo)
        .where(reservationMonthInfo.store.id.eq(storeId)
            .and(reservationMonthInfo.yearInfo.eq(year))
            .and(reservationMonthInfo.monthInfo.eq(month))
            .and(reservationDayInfo.dayInfo.eq(day)))
        .fetch();

  }

 

2. Builder사용하는 생성자 변경


일단 저는 Builder의 사용이유 중 하나가 객체를 생성할때 사용자가 넣고싶은 데이터만 넣을 수 있는, 객체 생성을 유연하게 할 수 있는 장점이 있기에 사용을 한다고 생각합니다.

그런데 지금 reservationInfo에 사용되고 있는 Builder를 보시면 

@Builder
  public ReservationDayInfo(ReservationMonthInfo reservationMonthInfo, ReservationDayRequestDto reservationDayRequestDto){
    this.reservationMonthInfo = reservationMonthInfo;
    this.dayInfo = reservationDayRequestDto.getDayInfo();
    this.timeInfo = reservationDayRequestDto.getTimeInfo();
    this.isAvailable = "Y";
    this.capacity = reservationDayRequestDto.getCapacity();
  }

dayInfo, timeInfo, capacity 컬럼을 넣기 위해서는 reservationRequestDto가 강요되고 있고,  reservationRequestDto를 넣으면, dayInfo, timeInfo, capacity는 강제로 set되게 됩니다.

dayInfo, timeInfo, capacity중 하나만 넣고 싶어도 못 넣게 되며, reservationRequestDto가 없이는 제대로 된 객체를 생성하기가 어렵죠.

이런 부분들이 제가 생각하는 Builder의 사용이유인 객체 생성의 유연성에 어긋나고,

현재 ReservationDayInfo에서는 강제로 set되는 컬럼들이 필수 컬럼이라 이런 상태가 문제가 없지만, 그렇지 않은 객체에서는,혹은 그렇지 않은 객체로 변경이 된다면 상당히 불편할 것이라고 생각합니다.

때문에 @Builder를 사용하는 생성자는 따로 두고, 위의 생성자는 일반 생성자로 사용해도 문제가 없을 것 같아 일반 생성자로 바꾸어 주었습니다.

또한, 변경 이전의 Builder패턴을 사용하는 코드들은 모두 일반 생성자를 사용하게 수정해 주었습니다.

 

변경된 코드

  public ReservationDayInfo(ReservationMonthInfo reservationMonthInfo, ReservationDayRequestDto reservationDayRequestDto){
    this.reservationMonthInfo = reservationMonthInfo;
    this.dayInfo = reservationDayRequestDto.getDayInfo();
    this.timeInfo = reservationDayRequestDto.getTimeInfo();
    this.isAvailable = "Y";
    this.capacity = reservationDayRequestDto.getCapacity();
  }

  @Builder
  public ReservationDayInfo(ReservationMonthInfo reservationMonthInfo, Integer dayInfo, String timeInfo, Integer capacity){
    this.reservationMonthInfo = reservationMonthInfo;
    this.dayInfo = dayInfo;
    this.timeInfo = timeInfo;
    this.isAvailable = "Y";
    this.capacity = capacity;
  }