[Spring] 페이지네이션 적용

Minit88·2023년 4월 20일
0

Spring

목록 보기
10/16
post-thumbnail

Lab_01 : 페이지네이션

도메인구성

  • Entity
    • Member
    • MeberPageInfo
  • Mapper
    • MemberMapper
    • ResponseMapper
    • ResponseMapperImpl
  • DTO
    • MemberResponseDto
  • Controller
    • MemberController
  • Service
    • MemberService
  • Repository
    • MemberRepository

Member 도메인에서의 페이지네이션을 구현을 예시로 실습해보려 한다.

페이지네이션을 위해 사용할 데이터들은 아래의 그림과 같다.

페이지네이션 요청

페이지네이션 메소드에 Get 방식으로 Page 번호와 데이터 갯수 Size를 쿼리문에 담아 요청을 보낸다.

요청을 보내게 되면 데이터베이스에서의 정보를 불러와 응답을 받도록 설계하려고 한다.

페이지네이션 설계

레포지토리 설계

먼저 페이지네이션에서 요구하는 하위 도메인은 pageInfo와 Member 들이 있다.

응답 받을 형태는 Map 형태로 data : {}, pageInfo : {} 을 응답으로 받는다.


[그림] 레포지토리 코드

  • data를 응답받기 위해서는 일단 레포지토리에 쿼리문을 작성하여 데이터베이스에 접근을 해 해당 데이터들을 불러오도록 설계한다. 아래의 코드는 data 응답을 받기 위한 코드이다.
  • 페이지와 사이즈는 memberId 기준으로 시작페이지인 startPage,마지막 페이지인 numPage 를 파라미터로 받아 WHEHRE 에서 해당 조건으로 해당 데이터를 불러온다.
  • MemberId는 1부터 시작한다.
  • pageInfo에서 총 데이터 수를 요구하기 때문에 SELECT COUNT(*) FROM MEMBER; 문을 작성하여 총 데이터 수를 구한다.
  • findMebers(),findCountTotalMembers() 메소드를 사용하여, 데이터베이스에서 응답을 받을 수 있다.

서비스 계층 설계


[그림] data 응답
서비스 설계

  • 페이지네이션의 data 를 응답으로 처리하기 위한 findMembers는 page,size를 파라미터로 입력받아 startPage를 page에 맞춰 설정하고 이를 레포지토리의 메소드인 findMembers() 를 이용하여 해당 범위의 데이터를 요청한다.
  • 응답 받은 데이터의 형태는 Meber 클래스로 이를 리스트에 담아서 응답을 받는다.


[그림] PageInfo 응답 서비스 설계

  • totalEelements 변수에 findCountTotal 메소드를 사용하여 총 데이터 개수로 초기화한다.
  • Builder을 사용하여 MemberPageInfo 객체를 생성해 리턴한다.

Controller 설계


[그림] 페이지네이션 컨트롤러 설계 코드

  • RequestParam으로 page,size를 입력으로 받는다.
  • page,size는 양수 값으로 설정된다.
  • data 정보는 service의 findMembers() 메소드를 이용하여 member형태의 List로 응답받고 이를 맵퍼를 이용해 MemberResponseDto로 변환한 리스트로 사용해 response에 저장한다.
  • PageInfo 정보는 page,size를 입력으로 받아 서비스에서 MemberPageInfo 를 response2 객체로 리턴 받는다.
  • responseMapper을 사용하여 response와 response2를 맵 형태로 리턴받고, 이를 HttpStatus와 함께 ResponseEntity 형태로 컨트롤러 응답값으로써 출력한다.

Lab_02 : 오류 사항

Response 응답을 Map 형태로 만들어주기 위해 responseMapper를 인터페이스 형태로 작성했고, 맵퍼를 구현한 클래스인 responseMapperImpl를 생성하였다.
오류는

Parameter 2 of constructor in com.codestates.member.controller.MemberController required a bean of type 'com.codestates.member.mapper.ResponseMapper' that could not be found.

MemberController에서 ResponseMapper가 의존성을 주입받지 못해 오류가 발생하였다.

    private final MemberService memberService;
    private final MemberMapper mapper;
    private final ResponseMapper responseMapper;
@Autowired
public MemberController(MemberService memberService, MemberMapper mapper,ResponseMapper responseMapper) {
        this.memberService = memberService;
        this.mapper = mapper;
        this.responseMapper = responseMapper;
    }

필드 부분과 생성자를 잘 작성하였다고 생각했었지만, 예상과는 달리 MemberResponseMapper을 주입 받지 못하고 있었다.
그래서 MemberResponseMapper의 주입 문제를 해결하기 위해 responseMapperImpl 클래스에 @Component 애너테이션을 붙여 의존성 주입이 가능하였고 MemberResponseMapper는 이 애너테이션을 통해 구현한 클래스를 참조받도록 하여 의존성 주입이 정상적으로 실행되게끔 수정하였다.

@Component
public class ResponseMapperImpl implements ResponseMapper{
    @Override
    public Map<String,Object> response(Object res1,Object res2){
        Map<String,Object> result = new HashMap<>();
        result.put("data",res1);
        result.put("pageInfo",res2);
        return result;
    }
}
profile
" To be BE "

0개의 댓글