
여기에서는 리스트 페이징 service쪽 구현하는 방법을 설명하겠습니다.
예로 드는 프로젝트의 실행구조는 Controller -> service -> service Implement -> mapper -> xml로 되어있습니다.
servicie ~ xml를 이 글에서 구현하도록 하겠습니다.
1.Mapper
SampleMapper.java
public interface SampleMapper {
public int selectRowCount();
public List<Sample> selectSampleList(SampleParam sampleParam);
}
selectRowCount = 게시물 총 개수 조회 쿼리
selectSampleList = 요청 페이지에 해당되는 위치의 리스트 조회 쿼리
2. query xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="위 SampleMapper.java 패키지.SampleMapper">
<select id="selectRowCount" resultType="Integer">
SELECT COUNT(seq)
FROM sample
</select>
<select id="selectSampleList" resultType="com.trandent.dto.Sample">
SELECT seq
, title
, regdate
FROM sample
ORDER BY seq DESC
LIMIT #{displayRow} OFFSET #{offset}
</select>
</mapper>
SampleMapper와 mapping되는 쿼리 입니다.
selectSampleList는 displayRow와 offset을 Parameter로 받아 리스트를 끊어서 가져오게 됩니다.
3. Service
SampleService.java
Parameter로 현재 페이지를 받습니다.
public interface SampleService {
public SampleResult pagingSample(int page) throws Exception;
}
4.SampleServiceImpl.java
Interface SampleService의 구현체 입니다.
@Repository
public class SampleServiceImpl implements SampleService {
//한 페이지당 리스트 개수
private static final int displayRow = 5;
//한번에 나타낼 페이지 개수 - 총 10페이지 일 경우 5개씩 끊어서 보여줌 1 2 3 4 5 >> << 6 7 8 9 10
private static final int pageCount = 5;
@Autowired
private SampleMapper sampleMapper;
@Override
public SampleResult pagingSample(int page) throws Exception {
// TODO Auto-generated method stub
//총 리스트개수 조회
int rowCount = sampleMapper.selectRowCount();
//페이징 계산 (현재페이지, 총 리스트수, 한 페이지에 나타낼 리스트수, 한 페이지에 나타날 페이징 개수)
Pagination pagination = this.getPagination(page, rowCount, displayRow, pageCount);
//화면에 보여줄 리스트 수와 계산된 오프셋으로 리스트 조회
SampleParam sampleParam = new SampleParam();
sampleParam.setDisplayRow(displayRow);
sampleParam.setOffset(pagination.getOffset());
List<Sample> sampleList = sampleMapper.selectSampleList(sampleParam);
//결과 세팅후 리턴
SampleResult sampleResult = new SampleResult();
sampleResult.setPagination(pagination);
sampleResult.setSampleList(sampleList);
return sampleResult;
}
public Pagination getPagination(int currentPage, int rowCount, int displayRow, int pageCount) throws Exception{
/*
* 예) 총 7페이지까지 있는데 현재 3페이지 일경우 페이징은 1 2 3 4 5 >> 출력되어야함
* currentPage = 3
* pageCount = 5 -> 한 화면에 리스트 5개씩 노출
* rowCount = 총 리스트 수 = 33개 가정
* startPage = 1
* endPage = 10에서 7로 변환하여 7
* lastPage = 7
* offset = 10 3페이지에 해당하는 리스트 열 시작점 -> 페이지당 5개의 리스트를 보여줄때 3페이지는 최근으로부터 16번째 리스트가 시작해야함 (화면출력 11 ~ 15번째이나 offset은 0부터 시작하기 때문에 10)
* 아래는 위 결과를 뽑기위한 계산식 아래 계산결과와 위의 예시가 맞으면 됨
*/
int startPage;
int endPage;
int lastPage;
int offset;
//시작 페이지 = 1 -> (3 - 1) / 5 * 5 + 1 = 1. (int형 이기때문에 2 / 5 = 0 나옴)
startPage = (currentPage - 1) / pageCount * pageCount + 1;
// 현재 페이징 노출구간의 마지막 페이지 = 5 -> 1 + 5 - 1 = 5
endPage = startPage + pageCount - 1;
//오프셋 = 10 -> 3페이지에 해당하는 리스트 시작위치 = (3 - 1) * 5
offset = (currentPage - 1) * displayRow;
//마지막 페이지 = 7 -> (33 / 5) + 1 = 6 + 1 = 7
lastPage = (rowCount / displayRow) + 1;
// 총 리스트 개수를 화면에 보여줄 개수로 mod 연산했을때 딱 맞아떨어진다면 마지막 페이지에서 -1 해줌 딱맞아 떨어지는 경우 마지막에 빈페이지가 나오기 때문
// 예시에서는 33 % 5 = 0이 아니기 때문에 빼주지 않음
if(rowCount % displayRow == 0){
lastPage--;
}
//현재 페이징 구간의 마지막 페이지가 실제 마지막 페이지보다 크다면 실제 마지막 페이지로 치환 시켜줌
//실제 데이터는 7페이지까지 있으나 pageCount를 5로 설정했다면 최초 계산시 마지막 페이지는 5의 배수로 나오기 때문에 (6 ~ 10페이지) 6 7 8 9 10
//실제 데이터가 있는 마지막 페이지로 치환하기 위함 10 -> 7 치환
if(endPage > lastPage){
endPage = lastPage;
}
Pagination pagination = new Pagination();
pagination.setCurrentPage(currentPage);
pagination.setEndPage(endPage);
pagination.setStartPage(startPage);
pagination.setLastPage(lastPage);
pagination.setPageCount(pageCount);
pagination.setRowCount(rowCount);
pagination.setDisplayRow(displayRow);
pagination.setOffset(offset);
return pagination;
}
}
동작순서는 리스트 총 개수 조회 -> 현재 페이지 기준으로 페이지 계산 -> 현재 페이지 기준으로 리스트 조회 -> 결과 리턴 입니다.
코드에 들어있는 주석은
1. 게시물의 총 개수가 33개
2. 화면에 보여지는 페이지 개수 5개 (예 : 1 2 3 4 5 >> / << 6 7 8 9 10 >> )
3. 화면에 보여지는 리스트 개수 5개
현재 3페이지 요청이 들어왔을 때의 페이징 처리한 값을 예로 들어 작성되었습니다.
다음 글에서는 컨트롤러와 화면에 대해 설명하도록 하겠습니다.