요르딩딩

스프링 페이징처리 본문

[Web]/[Back-End]

스프링 페이징처리

요르딩딩 2021. 1. 6. 13:56
728x90
반응형
페이징처리란
: 게사판의 여러개의 글 목록이 페이지별로 구분되어있을 경우, 이를 처리하는 방법을 일컫는다. 

 

내가 적은 방법은 3가지이다.

1. limit만 사용하는 경우

2. offset, limit를 사용하는 경우

3. 전체페이지가 없는 페이징처리의 경우 

 

게시판 페이징에는 3가지 상태값이 필요하다.

1. 현재 페이지 번호

2. 한번에 보여줄 페이지 개수

3. 한번에 보여줄 글의 개수

 

(주의) 총 데이터의 개수를 반환해 주어야 화면에서 몇페이지까지 보여줄지 정할 수 있습니다.

1. limit만 사용하는 경

MySQL의 limit만을 이용해 특정페이지를 조회하는 쿼리는 만들면 된다.

pageStart: (현재 보여줄 페이지 번호 - 1) * 한 페이지당 보여줄 게시글의 개수

perPageNum: 한 페이지당 보여줄 게시글의 개수이다.

limit (현재 보여줄 페이지 번호 - 1) * 한 페이지당 보여줄 게시글의 개수, 한 페이지당 보여줄 게시글의 개수

게시판은 여러종류일 수 있고, pageStart, perPageNum을 계산하는방법은 다른곳에서 도 많이 쓰일 수 있기때문에

별도의 클래스로 분리를하는 것이 좋다. > Util로 만들어서 사용해도 좋다.

package ~;

public class Criteria {

	private int page;  		    // 보여줄 페이지 번호
	private int perPageNum;   // 페이지당 보여줄 게시글의 개수
	
	public Criteria() {
		//최초 게시판에 진입할 때를 위해서 기본 값을 설정 해야 한다.
		this.page = 1;
		this.perPageNum = 10;
	}

	public int getPage() {
		return page;
	}

	public void setPage(int page) {
		if(page <= 0) {
			this.page = 1;
			return;
		}
		
		this.page = page;
	}

	public int getPerPageNum() {
		return perPageNum;
	}

	public void setPerPageNum(int perPageNum) {
		
		if(perPageNum <= 0 || perPageNum > 100) {
			this.perPageNum = 10;
			return;
		}
		
		this.perPageNum = perPageNum;
	}
	
	/* limit 구문에서 시작 위치를 지정할 때 사용된다. 예를 들어 10개씩 출력하는 경우 3페이지의 데이터는 linit 20, 10 과 같은 형태가 되어야 한다. */
	/* this.page 가 1이면 0이 되어야 한다 mysql limit 0, 10 해야 처음부터 10개씩 나온다. */
  /* 마이바티스 조회쿼리의 #{pageStart}에 전달된다. */
	public int getPageStart() {
		return (this.page -1) * perPageNum;
	}
	

	
	public String toString() {
		return "Criteria [page=" + page + ", perPageNum=" + perPageNum + "]";
	}
}

View단에서는 현재 페이지 정보페이지당 보여줄 게시글 개수 데이터를 가지고다녀야 한다고 한다.

 

[Util 적용]

int offset  = Util.calffset(pageNo, pageSize);
int limit   = Integer.parseInt(pageSize);
  
   
   public static int calPageNo(String limitStr, String offsetStr){
		if(EmptyUtil.isEmpty(limitStr) && EmptyUtil.isEmpty(offsetStr)) {
			return 0;
		}
		int limit = Integer.parseInt(limitStr); 
		int offset = Integer.parseInt(offsetStr); 
		return (limit + offset) / limit;
    }
	
	public static int calOffset(String pageNoStr, String pageSizeStr){
		if(EmptyUtil.isEmpty(pageNoStr) && EmptyUtil.isEmpty(pageSizeStr)) {
			return 0;
		}
		int pageNo = Integer.parseInt(pageNoStr); 
		int pageSize = Integer.parseInt(pageSizeStr); 
		return pageSize * (pageNo -1);
    }

 

참고 : www.hanumoka.net/2018/08/10/spring-20180810-spring-board-paging/

 

Spring MVC로 만드는 게시판 페이징 요점 정리(Thymeleaf기반 게시판)

항목 개발환경 비고 운영체제 Widnwos10(64) 백엔드프레임워크 Spring MVC 4 개발언어 java1.8 WAS Tomcat9 템플릿엔진 Thymeleaf3 템플릿엔진레이아웃 Tymeleaf-laout-dialect2 DB mysql8 ORM mybatis 들어가기난 내가 나름

www.hanumoka.net

2. offset, limit를 사용하는 경우

offset 10000, limit 20

위와 같이 질의를 하는경우 10,000부터 20개를 읽어야하니, 10,020개의 행을 읽어야합니다.

3. 페이징도 여러 기법들이 있는데, 전체 페이지 수 없는 페이징 기법은  빠릅니다.

"전체 페이지 수가 없다" 라는 말은 트위터같이 화면 맨 아래로 내려가면 [ ▼ next ] 이런식으로 "다음페이지" 링크만 있는 UI를 말합니다.

 

 기존 기법은 (총 게시물수 알고, 몇페이지 이동~)

select ~~ from ~~ limit 0, 20 (1페이지 셀렉트)

이때는 상관이 없는데, 100페이지쯤 가게되면.. (20개가 1페이지)

select ~~ from ~~ limit 20000 , 20 (100페이지, 20개 셀렉트)

내부에서는 20020개를 범위를 잡고 20000개를 거른다음에 20개를 데이터 뽑아옵니다.

페이지 아래로 내려갈수록 불필요한 탐색이 늘어납니다.

 

#인덱스가 잡혀있는, 시간순 일련번호 필드가 있으면 아래처럼 쿼리하면 됩니다. (스크롤)

 

 100페이지의 20개 레코드 중 맨 아래 레코드의 seq(14029 라고 칩시다)를 기억했다가

select ~~ from ~~ where seq < 14029 limit 0,20

이렇게 하면, 불필요한 100페이지분량의 20000 라인 탐색을 안해도 됩니다.

페이지가 뒤로 넘어가도 안정적인 쿼리성능을 확인할 수 있습니다.

 

 이런걸 페이지 수 없는 페이징 이라고 부릅니다.

페이지 수 없는 페이징은 맨 위에서부터 한페이지씩 내려오는 방법만 제공됩니다. 

1 2 3 4 5 6 7 8 9 10 .... 31이런식은 전통적인 페이징 기법

예를들어 트위터같이 화면 맨 아래로 내려가면 [ ▼ next ] 이런식으로 "다음페이지" 링크만 있는 UI 에서 seq를 알수있기 때문입니다.

 

참고 : https://to-dy.tistory.com/90?category=700248

728x90
반응형
Comments