Pageable, MyBatis를 통한 페이지네이션

Jin·2024년 1월 29일
1
post-thumbnail
from django.core.paginator import Paginator

한 줄이면 될 걸 온갖 난리를 쳐야하는 Springboot


버전 정보
Java: 17
spring boot: 3.2.2
mybatis springboot-starter: 3.0.3
mySQL

JPA의 시대, myBatis 깎는 나는 너무나 괴롭다. 자료가 너무 없다.

눈물겨운 여러가지 시도들

직접 구현하기 (귀찮아) -> pageHelper (뭔가 좀 그래) -> 직접 구현하기 2트 (이게 맞냐?) -> Pageable (성공이요)

페이지네이션은 자주 쓸 거 같아서 나를 위해 정리해서 저장할거다.

그냥 mapper.xml -> mapper.java -> service -> controller로 간다고 생각하면 된다.

dependency

spring-data-commons
여기서 gradle이던 maven이던 찾아서 넣기
나는 스프링도 최근 버전이고 해서 그냥 가장 최근 버전 넣는다.

mapper.xml

<-- 리스트 나열 -->
    <select id="list" parameterType="map" resultType="com.example.demo.room.dto.RoomDto">
        SELECT *
        FROM room
        LIMIT ${offset} , ${pageSize}
    </select>
<-- 개수 -->
    <select id="countRooms" resultType="int">
        SELECT COUNT(*) AS room_count
        FROM room
    </select>

mapper.java

@Mapper
public interface RoomMapper {
    List<Map<String, Object>> list (Map<String, Object> paramMap);
    int countRooms();
  }

service

RoomService (인터페이스)

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;

public interface RoomService {
    List<RoomDto> getRoomList();
    Page<Map<String, Object>> list (Map<String, Object> paramMap, Pageable page);

RoomServiceImpl.java

...
    @Override
    public Page<Map<String, Object>> list(Map<String, Object> paramMap, Pageable page) {
        paramMap.put("offset",page.getOffset());
        paramMap.put("pageSize",page.getPageSize());
        List<Map<String, Object>> contents = roomMapper.list(paramMap);
        int count = roomMapper.countRooms();
        return new PageImpl<>(contents,page,count);
    }
   ...

Controller.java

    @GetMapping
    @ResponseBody
    public ResponseEntity<Object> list(@RequestParam Map<String, Object> paramMap, @PageableDefault(value = 10) Pageable page){
        Map<String, Object> resultMap = new HashMap<String, Object>();
        
        Page<Map<String,Object>> result = roomService.list(paramMap,page);
        resultMap.put("pages", result);
        resultMap.put("size", page.getPageSize());

            return ResponseEntity.ok()
                    .body(resultMap);
    }

@PageableDefault(value=10) 이게 딱봐도 한 페이지당 max 개수

Postman에서는 잘뜰까?

http://localhost:8080/room?page=1

딸깍

{
    "pages": {
        "content": [
        (생략)
        ],
        "pageable": {
            "pageNumber": 1,
            "pageSize": 2,
            "sort": {
                "empty": true,
                "sorted": false,
                "unsorted": true
            },
            "offset": 2,
            "unpaged": false,
            "paged": true
        },
        "last": false,
        "totalPages": 6,
        "totalElements": 11,
        "size": 2,
        "number": 1,
        "sort": {
            "empty": true,
            "sorted": false,
            "unsorted": true
        },
        "first": false,
        "numberOfElements": 2,
        "empty": false
    },
    "size": 2
}

(대충 잘뜬다는 글)

나의 은인이자 출처

[다음편] 지옥의 Vue.js 페이지네이션편
은 없고 어쩌다보니 React로 하게 되었습니다.

profile
go-getter

4개의 댓글

comment-user-thumbnail
2024년 2월 28일

다음화 예고 기대되네요

답글 달기
comment-user-thumbnail
2024년 2월 28일

다음화 예고 기대되네요

1개의 답글
comment-user-thumbnail
2024년 6월 18일

공감이 되네요 ... 지긋지긋한 레거시.. 새 프로젝트 만들 때도 MyBatis를 쓰는 그들..

답글 달기