이번 글에는 저번글에서 구현만하고 넘어갔던 페이징기법에 대해서 공부해보도록 하겠습니다.
우선 페이징에 필요한 변수들을 선언해놧던 Criteria부터 살펴보도록 하겠습니다.
package com.example.starter.pageing;
import org.springframework.web.util.UriComponents;
import org.springframework.web.util.UriComponentsBuilder;
import lombok.Data;
@Data
public class Criteria {
/** 현재 페이지 번호 */
private int currentPageNo;
/** 페이지당 출력할 데이터 개수 */
private int recordsPerPage;
/** 화면 하단에 출력할 페이지 사이즈 */
private int pageSize;
/** 검색 키워드 */
private String searchKeyword;
/** 검색 유형 */
private String searchType;
public Criteria() {
this.currentPageNo = 1;
this.recordsPerPage = 10;
this.pageSize = 10;
}
public String makeQueryString(int pageNo) {
UriComponents uriComponents = UriComponentsBuilder.newInstance()
.queryParam("currentPageNo", pageNo)
.queryParam("recordsPerPage", recordsPerPage)
.queryParam("pageSize", pageSize)
.queryParam("searchType", searchType)
.queryParam("searchKeyword", searchKeyword)
.build()
.encode();
return uriComponents.toUriString();
}
}
1. currentPageNo : 현재 보여지고 있는 페이지의 번호를 뜻합니다.
2. recordPerPage : 한페이지당 보여질 게시물 갯수입니다. 6으로 되면 한페이지당 6개의 글을 보여줍니다.
3. pageSize : 하단에 출력될 페이지 번호 수 입니다.
4. searchKeyword : 검색 기능 사용시 사용될 검색어 변수 입니다.
5. searchType : 검색 기능 사용시 사용될 검색 필터변수 입니다( (예) 작성자 , 내용, 제목) )
6. 생성자 초기화 : 객체 생성시 초기값들을 지정해줍니다.
7. makeQueryString :
다음은 Dao 부분을 보겠습니다
<select id="selectArticleList" parameterType="Article" resultType="Article">
SELECT
*
FROM
article
ORDER BY
aid DESC
LIMIT
#{paginationInfo.firstRecordIndex}, #{recordsPerPage}
</select>
MySQL에서는 페이징을 LIMIT문을 이용하여 처리합니다.
LIMIT 10 ,20 ; 이라고하면 10번쨰 레코드부터 시작해서 10개를 가져온다 라는 의미입니다.
Dao에서는 시작 레코드 번호 부터 recordsPerPage 페이지당 보여줄 게시물 갯수만큼 가져와서 보여주겠다는 의미입니다.
자 다음은 Pagin 계산 클래스PaginationInfo 를 보겠습니다.
package com.example.starter.pageing;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
@Data
public class PaginationInfo {
/** 페이징 계산에 필요한 파라미터들이 담긴 클래스 */
private Criteria criteria;
/** 전체 데이터 개수 */
private int totalRecordCount;
/** 전체 페이지 개수 */
private int totalPageCount;
/** 페이지 리스트의 첫 페이지 번호 */
private int firstPage;
/** 페이지 리스트의 마지막 페이지 번호 */
private int lastPage;
/** SQL의 조건절에 사용되는 첫 RNUM */
private int firstRecordIndex;
/** SQL의 조건절에 사용되는 마지막 RNUM */
private int lastRecordIndex;
/** 이전 페이지 존재 여부 */
private boolean hasPreviousPage;
/** 다음 페이지 존재 여부 */
private boolean hasNextPage;
public PaginationInfo(Criteria criteria) {
if (criteria.getCurrentPageNo() < 1) {
criteria.setCurrentPageNo(1);
}
if (criteria.getRecordsPerPage() < 1 || criteria.getRecordsPerPage() > 100) {
criteria.setRecordsPerPage(10);
}
if (criteria.getPageSize() < 5 || criteria.getPageSize() > 20) {
criteria.setPageSize(10);
}
this.criteria = criteria;
}
public void setTotalRecordCount(int totalRecordCount) {
this.totalRecordCount = totalRecordCount;
if (totalRecordCount > 0) {
calculation();
}
}
private void calculation() {
/* 전체 페이지 수 (현재 페이지 번호가 전체 페이지 수보다 크면 현재 페이지 번호에 전체 페이지 수를 저장) */
totalPageCount = ((totalRecordCount - 1) / criteria.getRecordsPerPage()) + 1;
if (criteria.getCurrentPageNo() > totalPageCount) {
criteria.setCurrentPageNo(totalPageCount);
}
/* 페이지 리스트의 첫 페이지 번호 */
firstPage = ((criteria.getCurrentPageNo() - 1) / criteria.getPageSize()) * criteria.getPageSize() + 1;
/* 페이지 리스트의 마지막 페이지 번호 (마지막 페이지가 전체 페이지 수보다 크면 마지막 페이지에 전체 페이지 수를 저장) */
lastPage = firstPage + criteria.getPageSize() - 1;
if (lastPage > totalPageCount) {
lastPage = totalPageCount;
}
/* SQL의 조건절에 사용되는 첫 RNUM */
firstRecordIndex = (criteria.getCurrentPageNo() - 1) * criteria.getRecordsPerPage();
/* SQL의 조건절에 사용되는 마지막 RNUM */
lastRecordIndex = criteria.getCurrentPageNo() * criteria.getRecordsPerPage();
/* 이전 페이지 존재 여부 */
hasPreviousPage = firstPage != 1;
/* 다음 페이지 존재 여부 */
hasNextPage = (lastPage * criteria.getRecordsPerPage()) < totalRecordCount;
}
}
1.criteria : 페이징 계산에 필요한 변수들을 저장해놓은 criteria입니다
2. totalRecordCount : 총 게시물 갯수입니다. dao에 getTotalCount()를 이용해서 가져올 수 있습니다.
3. totalPageCount : 게시물에 따라 생기는 페이지 갯수입니다.
4. firstPage : 페이지에 따른 첫 게시물의 번호입니다.
5. lastPage : 페이지에 따른 마지막 게시물의 번호입니다.
6. firstRecordIndex : limit절에 사용할 첫번째 인자입니다.
7. lastRecordIndex : Oracle 등 Limit절이 없는 db 에서 필요한 변수입니다. Mysql에서는 사용안해도됩니다.
7. hasPreviousPage : 이전 페이지 존재 여부를 저장할 변수입니다.
8. hasNextPage : 다음 페이지 존재 여부를 저장할 변수 입니다.
PaginationInfo(Critera criteria)
- 만약 현재페이지가 0보다 작으면 현재페이지를 1로 저장해줍니다.
- 한 페이지당 보여질 게시물의 갯수가 1보다 작거나 100보다 크면 10으로 다시 세팅해줍니다.
- 페이지 갯수가 5개 아래거나 20개 이상이면 10개로 맞춰줍니다.
calculation 메소드
-totalPageCount = (전체 데이터 갯수 - 1)/페이지당 출력할 데이터 수 )+1입니다.
만약 30개 데이터가있고 페이지당 10개를 출력한다면
(30-1)/10 +1 = 2.9+1 = 3.9로 3이됩니다.
-firstPage = (현재페이지 번호 -1)/ 페이지의 갯수)* 페이지의 갯수 +1입니다.
현재 페이지가 13페이지이고 페이지의 갯수를 10개씩 한다고하면
(13-1)/10*10+1 -> (1.2=1)*10+1 =11이됩니다.
-lastPage = ( 첫 페이지 번호 + 페이지 갯수) -1입니다.
현재 페이지가 13페이지고 페이지의 갯수를 10개씩이라고하면
firstPage를 구하면 11이되고 11+10-1 = 20이됩니다.
이렇게 페이징에 필요한 변수와 계산법을 알아봤구요
이제 CommonDto를 만들고 상속시키고 사용하는지 알아보겠습니다
Controller는 본 목적이 뷰에 데이터를 전달하는 목적입니다.
때문에 Critria, PaginationInfo 등을 그대로 쓰면 컨트롤러 단에서 불필요한 코드가 생깁니다.
이를 MVC패턴에 맞게 바꾸기위함입니다.
// 사용 중인 전체 게시글 수를 구한다.
int boardTotalCount = boardService.getBoardTotalCount(criteria);
// PaginationInfo 클래스의 객체를 생성하여 전체 게시글 수를 저장한다.
PaginationInfo paginationInfo = new PaginationInfo(criteria);
paginationInfo.setTotalRecordCount(boardTotalCount);
// 계산된 페이징 정보를 뷰로 전달한다.
model.addAttribute("paginationInfo", paginationInfo);
출처-https://congsong.tistory.com/26
'자바 > 스프링부트 기초' 카테고리의 다른 글
스프링부트! 게시판 만들면서 배우기! 5. 게시물 상세정보 구현하기 (0) | 2021.04.29 |
---|---|
스프링부트! 게시판 만들면서 배우기! 4. 게시물 작성하기 (0) | 2021.04.29 |
스프링부트! 게시판 만들면서 배우기! 3. 리스트 구현하기 (0) | 2021.04.25 |
스프링부트! 게시판 만들면서 배우기! 3.로그인, 회원가입 구현하기 (0) | 2021.04.23 |
스프링부트! 게시판 만들면서 배우기! 2. 인덱스 페이지만들기 (0) | 2021.04.22 |