MyBatis Mapper에서 Pageable 사용하기

Spring Data, Mybatis

Posted by 김우원 on September 23, 2023

JPA, MongoDB 등은 Spring Data의 Repository라는 인터페이스를 활용하여 저장소의 데이터에 접근을 친숙하고 일관되게 제공합니다.

특히, Pagination을 구현할 때, Spring Data의 Pageable이라는 객체를 사용하면, 매우 편리하게 구현할 수 있습니다. 이번 게시물에서는 Pageable 객체를 MyBatis Mapper에서 활용하는 법을 알아보도록 하겠습니다.

Pageable

Controller에서 다음과 같이 인자로 Pageable객체를 넘겨주면, 요청의 Query String으로 부터 간편하게 Pageable 객체를 주입받을 수 있다. (해당 역할은 PageableHandlerMethodArgumentResolver가 수행한다)

GET /search?page=3&size=10&sort=createdAt,DESC

1
2
3
4
5
6
@GetMapping("/search")
public ApiResponse<PopupStoresResponse> search(PopupStoreQueryRequest request, Pageable pageable) {
    log.info("query: {}, pageable: {}", request, pageable);
    var list = popupStoreService.getPopupStoresByQuery(request, pageable);
    return ApiResponse.success(PopupStoresResponse.from(list));
}

Mapper

Mybatis의 Mapper XML에서 다음과 같이 Pageable 객체를 사용할 수 있다. (DBMS: Oracle)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
  <select id="selectPopupStoresByQuery" resultMap="popupStoreMap"
    parameterType="com.bonestew.popmate.popupstore.persistence.dto.PopupStorePageDto">
	  .
      .
      .
    </where>
    <if test="pageable.sort.sorted">
      <trim prefix="order by">
        <foreach item="order" index="i" collection="pageable.sort" separator=", ">
          ${order.property} ${order.direction}
        </foreach>
      </trim>
    </if>
    OFFSET ${pageable.page}*${pageable.size} ROWS FETCH FIRST ${pageable.size} ROWS ONLY
  </select>
  1. pageable.getSort().isSorted()는 요청에 정렬이 포함되어 있으면 true아니면 false를 반환한다.
  2. pageable.getSort()를 통해 정렬 요청을 담은 Sort(Streamable) 객체를 받을 수 있다.
  3. Sort의 각 아이템을 통해 정렬 하고자 하는 필드명, 방향을 조회할 수 있다.
  4. Pageable의 getPage()getSize()를 통해 페이지 정보와, 사이즈 정보를 조회할 수 있다.