-
[과제] 일정 관리 앱 만들기 도전 Lv4내일배움캠프/과제 2025. 3. 25. 18:15
✅ Lv4. 페이지네이션
1️⃣ 과제 조건
- 설명
- 많은 양의 데이터를 효율적으로 표시하기 위해 데이터를 여러 페이지로 나눕니다.
- 페이지 번호와 페이지 크기를 쿼리 파라미터로 전달하여 요청하는 항목을 나타냅니다.
- 전달받은 페이지 번호와 크기를 기준으로 쿼리를 작성하여 필요한 데이터만을 조회하고 반환
- 많은 양의 데이터를 효율적으로 표시하기 위해 데이터를 여러 페이지로 나눕니다.
- 조건
- 등록된 일정 목록을 페이지 번호와 크기를 기준으로 모두 조회
- 조회한 일정 목록에는 작성자 이름이 포함
- 범위를 넘어선 페이지를 요청하는 경우 빈 배열을 반환
- Paging 객체를 활용할 수 있음
2️⃣ 목록 조회 시 조건 매개변수 변경
1. Paging 객체 생성
public class CustomPageable {@Schema(description = "페이지 번호 (1부터 시작)", defaultValue = "1")private int page = 1;@Schema(description = "페이지 크기", defaultValue = "10")private int size = 10;public int getOffset() {return (this.page - 1) * this.size;}}2. 조건 객체 생성
public class ScheduleSearchDto {@Schema(description = "작성자 PK")private Long writerId;@Schema(description = "수정일")private String modDt;}3. Controller 매개변수 변경
@GetMappingpublic BaseResponse<List<ScheduleResDto>> findAllSchedule(@ParameterObject CustomPageable pageable, @ParameterObject ScheduleSearchDto dto) {return BaseResponse.from(scheduleService.findAllSchedule(pageable, dto));}4.Service
public List<ScheduleResDto> findAllSchedule(CustomPageable pageable, ScheduleSearchDto dto) {return scheduleRepository.findAllSchedule(pageable, dto).stream().map(ScheduleResDto::new) // 일정 목록 조회 후 mapping.collect(Collectors.toList());}5.Repository
Limit, Offset 을 사용하여 페이징 처리
public List<Schedule> findAllSchedule(CustomPageable pageable, ScheduleSearchDto dto) {List<Object> params = new ArrayList<>();StringBuilder query = new StringBuilder().append("SELECT a.id, a.schedule, a.password, a.reg_dt, a.mod_dt\n").append(" ,b.id AS writer_id, b.email, b.name, b.reg_dt as writer_reg_dt, b.mod_dt as writer_mod_dt\n").append(" FROM schedule a JOIN writer b ON a.writer_id = b.id\n").append(" WHERE a.del_dt IS NULL \n");if (dto.getWriterId() != null) { // 작성자 PK 검색조건이 있을 경우query.append(" AND b.id = ? \n");params.add(dto.getWriterId());}if (StringUtils.isNotBlank(dto.getModDt())) { // 수정일 검색조건이 있을 경우query.append(" AND DATE(a.mod_dt) = ? \n");params.add(dto.getModDt());}query.append(" ORDER BY a.mod_dt DESC \n").append(" LIMIT ? OFFSET ?");// 페이징 계산params.add(pageable.getSize()); // LIMIT 몇 개 가져올지params.add(pageable.getOffset()); // OFFSET (page 번호 * size)return jdbcTemplate.query(query.toString(), params.toArray(), this.scheduleRowMapper());}3️⃣ 페이지네이션 결과 객체
페이지네이션을 도입 후 페이징 처리를 하기 위해 return 객체에 페이징 정보랑 총 데이터 수를 return 해주기로함
1. 페이지네이션 결과 객체 생성
제네릭을 사용하여 유연하게 대응
public class PaginationResDto<T> {@Schema(description = "결과 Data 목록")private List<T> data;@Schema(description = "총 Data 수")private Long total;@Schema(description = "한 페이지에 표시할 데이터 개수")private Integer size;@Schema(description = "페이지 번호")private Integer page;@Schema(description = "총 페이지 수")private Long totalPages;}2. Controller Return 객체 변경
@GetMappingpublic BaseResponse<PaginationResDto<ScheduleResDto>> findAllSchedule(@ParameterObject @Valid CustomPageable pageable, @ParameterObject ScheduleSearchDto dto) {return BaseResponse.from(scheduleService.findAllSchedule(pageable, dto));}3. Service, Return 객체 변경 및 총 데이터 수 조회 로직 추가
public PaginationResDto<ScheduleResDto> findAllSchedule(CustomPageable pageable, ScheduleSearchDto dto) {long totalCnt = scheduleRepository.findAllScheduleCount(dto);List<ScheduleResDto> resultList = scheduleRepository.findAllSchedule(pageable, dto).stream().map(ScheduleResDto::new) // 일정 목록 조회 후 mapping.collect(Collectors.toList());return PaginationResDto.<ScheduleResDto>builder().data(resultList).total(totalCnt).size(pageable.getSize()).page(pageable.getPage()).totalPages((totalCnt + pageable.getSize() - 1) / pageable.getSize()).build();}4.Repository 총 데이터 수 조회
public long findAllScheduleCount(ScheduleSearchDto dto) {List<Object> params = new ArrayList<>();StringBuilder query = new StringBuilder().append("SELECT count(*) \n").append(" FROM schedule a JOIN writer b ON a.writer_id = b.id\n").append(" WHERE a.del_dt IS NULL \n");if (dto.getWriterId() != null) { // 작성자 PK 검색조건이 있을 경우query.append(" AND b.id = ? \n");params.add(dto.getWriterId());}if (StringUtils.isNotBlank(dto.getModDt())) { // 수정일 검색조건이 있을 경우query.append(" AND DATE(a.mod_dt) = ? \n");params.add(dto.getModDt());}return jdbcTemplate.queryForObject(query.toString(), params.toArray(), Long.class);}'내일배움캠프 > 과제' 카테고리의 다른 글
[과제] 일정 관리 앱 JPA (0) 2025.04.04 [과제] 일정 관리 앱 만들기 도전 Lv5, Lv6 (0) 2025.03.25 [과제] 일정 관리 앱 만들기 도전 Lv3 (0) 2025.03.25 [과제] 일정 관리 앱 만들기 필수 Lv2 (0) 2025.03.25 [과제] 일정 관리 앱 만들기 필수 Lv1 (0) 2025.03.25 - 설명