-
[과제] 일정 관리 앱 만들기 도전 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 매개변수 변경
@GetMapping public 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 객체 변경
@GetMapping public 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 - 설명