6주차 미션 [빈]#23
Conversation
| @Query(""" | ||
| select m | ||
| from Mission m | ||
| where m.store.region.id = :regionId | ||
| and ( | ||
| :memberId is null | ||
| or m.id not in ( | ||
| select mm.mission.id | ||
| from MemberMission mm | ||
| where mm.member.id = :memberId | ||
| ) | ||
| ) | ||
| order by m.id desc | ||
| """) |
There was a problem hiding this comment.
NOT IN은 서브쿼리 결과에 NULL이 포함될 경우 의도치 않은 결과가 나올 수 있고, 데이터가 늘어날수록 NOT EXISTS나 LEFT JOIN에 비해 성능이 떨어질 우려가 있습니다. 따라서 NOT EXISTS로 변경하면 좋을 것 같습니다!
| @Override | ||
| public MissionResDto.MemberMissionPageResponse getMemberMissions(Long memberId, MemberMissionStatus status, Integer page) { | ||
| int pageNumber = Math.max(page, 1) - 1; | ||
| PageRequest pageRequest = PageRequest.of(pageNumber, 10); |
There was a problem hiding this comment.
페이지 사이즈 10이 하드코딩 되어 있는데 클래스 상단에 상수를 선언하거나 클라이언트 단에서 사이즈를 받도록 수정하면 좋을 것 같습니다!
| int pageNumber = Math.max(page, 1) - 1; | ||
| PageRequest pageRequest = PageRequest.of(pageNumber, 10); | ||
|
|
||
| Page<MemberMission> memberMissionPage = memberMissionRepository.findMemberMissionsByStatus( |
There was a problem hiding this comment.
Page는 전체 데이터 개수를 파악하기 위해 매 조회마다 COUNT 쿼리를 실행하는데 무한 스크롤 특성상 전체 페이지 수를 알 필요가 없기 때문에 Page 대신 Slice를 활용해도 좋을 것 같습니다! Slice는 요청한 사이즈보다 1개 더 많은 데이터를 조회하여 hasNext 여부만 판단해서 불필요한 쿼리를 방지할 수 있습니다
| public record MemberMissionPageResponse( | ||
| List<MemberMissionPageItem> missions, | ||
| Integer listSize, | ||
| Integer totalPage, | ||
| Long totalElements, | ||
| Boolean isFirst, | ||
| Boolean isLast | ||
| ) { | ||
| } | ||
|
|
||
| public record HomeMissionPageResponse( | ||
| List<HomeMissionPageItem> missions, | ||
| Integer listSize, | ||
| Integer totalPage, | ||
| Long totalElements, | ||
| Boolean isFirst, | ||
| Boolean isLast | ||
| ) { | ||
| } |
There was a problem hiding this comment.
페이징 메타데이터를 생성하는 로직이 완전히 중복되고 있는데 새로운 페이징 목록이 추가될 때마다 동일한 코드를 쓰게 되고, 응답 규격이 변경되면 수정해야 하는 부분이 늘어나기 때문에 공통 페이징 응답을 도입하는 것이 좋습니다!
| MISSION_NOT_FOUND(HttpStatus.NOT_FOUND, "MISSION404", "Mission not found."), | ||
| STORE_NOT_FOUND(HttpStatus.NOT_FOUND, "STORE404", "Store not found."); |
There was a problem hiding this comment.
특정 도메인의 데이터가 존재하지 않는 에러는 해당 도메인의 에러 코드 클래스에서 관리하는 것이 좋습니다! MissionErrorCode에는 미션과 관련된 예외만 남겨두면 됩니다
| REVIEW_NOT_FOUND(HttpStatus.NOT_FOUND, "REVIEW404", "Review not found."), | ||
| MEMBER_NOT_FOUND(HttpStatus.NOT_FOUND, "MEMBER404", "User not found."), | ||
| STORE_NOT_FOUND(HttpStatus.NOT_FOUND, "STORE404", "Store not found."); |
🚩 관련 이슈
📌 구현 결과
@Query기반 페이징 조회 구현❓ 리뷰 요청
🤔 질문
💬 기타 공유 사항