반응형
1. 서론
페이징 처리란? 페이징 처리는 많은 양의 데이터를 한 번에 모두 가져오는 대신, 일부만 가져와서 화면에 보여주는 기법입니다. 이를 통해 성능을 개선하고 사용자의 경험을 향상시킬 수 있습니다.
왜 페이징 처리가 필요한가? 대량의 데이터를 한 번에 처리하면 메모리와 성능에 큰 부담을 주게 됩니다. 페이징 처리를 통해 필요한 데이터만 가져와서 처리함으로써 이러한 문제를 해결할 수 있습니다.
2. 페이징 처리의 기본 개념
페이징의 기본 원리
- 데이터를 일정한 크기로 나누어 각 페이지에 해당하는 부분만 가져오는 방식입니다.
- 클라이언트에서 요청하는 페이지 번호와 한 페이지당 항목 수를 기준으로 데이터베이스에서 필요한 부분만 쿼리합니다.
주요 용어
- 페이지(Page): 데이터를 나누는 단위입니다.
- 오프셋(Offset): 현재 페이지의 시작 지점을 나타냅니다.
- 한 페이지당 항목 수: 한 페이지에 표시할 데이터의 개수입니다.
3. 페이징 처리 구현 예제
Spring Boot와 MyBatis를 이용한 페이징 처리
4. 코드 예제
Controller
@RestController
@RequestMapping("/api/qna")
public class QnaController {
private final QnaService qnaService;
@Autowired
public QnaController(QnaService qnaService) {
this.qnaService = qnaService;
}
@GetMapping("/")
public ModelAndView getIndex(
@RequestParam(value = "tab", required = false, defaultValue = "help") String tab,
@RequestParam(value = "page", required = false, defaultValue = "1") int page) {
ModelAndView modelAndView = new ModelAndView("qna/index");
int totalArticles = qnaService.getArticleTotalCount(tab);
PagingModel pagingModel = new PagingModel(totalArticles, page);
List<QnaArticleEntity> articles = qnaService.getArticlesByTab(tab, pagingModel);
modelAndView.addObject("articles", articles);
modelAndView.addObject("pagingModel", pagingModel);
return modelAndView;
}
}
Model (Model로 PagingModel로 만들어 사용하는 방식이 효율적입니다.)
public class PagingModel {
// 기본적으로 한 페이지에 표시할 행(row)의 개수
public static final int DEFAULT_ROW_COUNT_PER_PAGE = 20;
// 전체 행(row)의 개수 (총 게시글의 개수)
private final int totalRowCount;
// 요청된 페이지 번호
private final int requestPage;
// 한 페이지에 표시할 행(row)의 개수
private final int rowCountPerPage;
/**
* 생성자: 전체 행(row)의 개수와 요청된 페이지 번호를 받아서 PagingModel 객체를 생성한다.
*
* @param totalRowCount 전체 행(row)의 개수
* @param requestPage 요청된 페이지 번호
*/
public PagingModel(int totalRowCount, int requestPage) {
// 전체 행(row)의 개수를 설정
this.totalRowCount = totalRowCount;
// 요청된 페이지 번호가 1보다 작으면 1로 설정
this.requestPage = requestPage < 1 ? 1 : requestPage;
// 기본 행(row) 개수를 설정
this.rowCountPerPage = DEFAULT_ROW_COUNT_PER_PAGE;
}
/**
* @return 현재 페이지에서의 시작 인덱스 (0부터 시작)
*/
public int getStartIndex() {
return (requestPage - 1) * rowCountPerPage;
}
/**
* @return 한 페이지에 표시할 행(row)의 개수
*/
public int getRowCountPerPage() {
return rowCountPerPage;
}
}
Service
@Service
public class QnaService {
private final QnaMapper qnaMapper;
@Autowired
public QnaService(QnaMapper qnaMapper) {
this.qnaMapper = qnaMapper;
}
public int getArticleTotalCount(String tab) {
return qnaMapper.countArticlesByTab(tab);
}
public List<QnaArticleEntity> getArticlesByTab(String tab, PagingModel pagingModel) {
return qnaMapper.selectArticlesByTab(tab, pagingModel.getStartIndex(), pagingModel.getRowCountPerPage());
}
}
Mapper
@Mapper
public interface QnaMapper {
@Select("SELECT COUNT(*) FROM qna_articles WHERE category = #{tab}")
int countArticlesByTab(@Param("tab") String tab);
@Select("SELECT * FROM qna_articles WHERE category = #{tab} LIMIT #{count} OFFSET #{offset}")
List<QnaArticleEntity> selectArticlesByTab(@Param("tab") String tab, @Param("offset") int offset, @Param("count") int count);
}
SQL 쿼리
SELECT COUNT(*) FROM qna_articles WHERE category = #{tab};
SELECT * FROM qna_articles WHERE category = #{tab} LIMIT #{count} OFFSET #{offset};
5. 결론
페이징 처리의 이점
- 성능 향상: 필요한 데이터만 가져와서 처리하기 때문에 성능이 크게 향상됩니다.
- 사용자 경험 개선: 빠른 응답 시간과 필요한 정보만 보여줌으로써 사용자 경험이 향상됩니다.
페이징 처리 시 주의사항
- 페이지 번호와 같은 입력 값은 항상 유효성을 검사해야 합니다.
- 페이지를 이동할 때마다 동일한 쿼리를 반복적으로 실행하지 않도록 캐싱 등을 고려할 수 있습니다.
반응형
'Spring Boot' 카테고리의 다른 글
메서드 체이닝과 빌더 패턴을 활용한 엔티티 클래스 구현 (0) | 2024.06.24 |
---|---|
댓글 시스템 데이터베이스(MySQL) 설계 및 MyBatis를 이용한 댓글 수 조회 (0) | 2024.06.24 |
스프링 부트에서 @Transactional을 활용한 트랜잭션 관리 (0) | 2024.06.21 |
미디어 관련 공부#3 (0) | 2022.09.12 |
미디어 관련 공부#2 (0) | 2022.08.30 |