게시판 페이징 기능 만들기
스프링 목록
- Spring(1) - 백엔드 초기설정
- Spring(2) -스프링 Client 파일 업로드(1)
- Spring(3) -스프링 Client 파일 업로드(2)
- Spring(4) - 백엔드 RESTFULL 로 바꾸기
- Spring(5) - 게시판 페이징 기능 추가하기
- Spring(6) - 검색 기능 추가
- Spring(7) - 프론트 ContextPath 동적 설정
스프링 부트 목록
- Spring Boot(1) - 스프링 부트 초기설정
- Spring Boot(2) - JPA 사용해 보기
- Spring Boot(3) - JPA 방향설정, 관계설정
- Spring Boot(4) - JPA 심화
- Spring Boot(5) - JPA 일대일 실습
게시판에 피이징 기능을 추가하는 이유?
프로젝트 초기에는 모든 글을 다 읽어와도 성능상 별차이가 없지만, 글의 수가 많아 지면 많아질수록 DB에 부하가 걸릴 가능성이 높아지기 때문에 쪼개서 특정 갯 수 만큼 불러옵니다.
해야 할것들
- DB에
START_ROW
,END_ROW
함수 만들어주기 (페이징떄 사용함)- SQL 구문에
rownum
처리 해주기- Controller의
list()
부분 매개변수로 페이지 번호 수 설정해주기- DAO , Service , RepBoardMapper 수정해주기 (페이징 처리)
- 페이지 정보가 담긴
DTO
만들어주기- Front JS 수정해주기
ORACLE (SQL DEVELOPER )
1. DB에 페이징 함수 추가하기
crr_page : 현재 페이지 cnt_per_page : 한 페이지 당 게시글 수.
create or replace FUNCTION START_ROW(crr_page number, cnt_per_page number)
return number
IS
start_row number;
BEGIN
start_row := (crr_page -1)*cnt_per_page +1;
return start_row;
END;
create or replace FUNCTION END_ROW(crr_page number, cnt_per_page number)
return number
IS
start_row number;
BEGIN
start_row := crr_page *cnt_per_page;
return start_row;
END;
5개씩 읽어오는 페이지의 1페이지 시작과 끝
START_ROW(1, 5) =1
END_ROW(1, 5) =5
5개씩 읽어오는 페이지의 2페이지 시작과 끝
START_ROW(2, 5) =6
END_ROW(2, 5) =10
2. SQL 로 함수 테스트 하기
SELECT *
FROM (
SELECT rownum r , a.*
FROM (
SELECT level,
R.board_no,
R.parent_no,
R.board_id "boardC.id",
R.board_title,
R.board_content,
R.board_viewcount,
R.board_dt
FROM repboard R
START WITH R.parent_no = 0
CONNECT BY PRIOR R.board_no = R.parent_no
ORDER SIBLINGS BY R.board_no DESC
) a
)
WHERE r BETWEEN START_ROW(1,5) AND END_ROW(1,5);
제대로 쿼리문 5개씩 읽어오는 지 확인
Spring (이클립스)
3. RepboardMapper.xml
findAll
수정parameterType = "map"
추가
<map>
에currentPage
,cntPerPage
넣어 줄거
<select id="findAll" resultType="Repboard" parameterType="map">
SELECT *
FROM (
SELECT rownum r ,a.*
FROM (
SELECT level,
R.board_no,
R.parent_no,
R.board_id "boardC.id",
R.board_title,
R.board_content,
R.board_viewcount,
R.board_dt
FROM repboard R
START WITH R.parent_no = 0
CONNECT BY PRIOR R.board_no = R.parent_no
ORDER SIBLINGS BY R.board_no DESC
) a
)
WHERE r BETWEEN START_ROW(#{currentPage},#{cntPerPage}) AND END_ROW(#{currentPage},#{cntPerPage})
</select>
4. PageDTO.java
(com.my.dto/PageDTO.java)
DTO 내부에서
startPage
,endPage
,totalPage
내부로 적으로 초기화 해주기
public class PageDTO<T> {
private String url; //ex. board/list
private int currentPage = 1; //현재페이지
static public int CNT_PER_PAGE = 5; //한 페이지당 출력되는 게시물 갯수
// 그룹 당 페이지 수 ex)3이면 (1~3페이지) (4~6페이지)(7~9페이지) 이런식
static public int CNT_PER_PAGE_GROUP = 3;
private int totalCnt; //DB 내의 총 게시물 갯수
private int totalPage; //총페이지수
private int startPage; //시작페이지
private int endPage; //끝페이지
private List<T> list; //ex. 게시글목록
public PageDTO() {
super();
}
public PageDTO(String url, int totalCnt, List<T> list) {
this(url, 1, totalCnt, list);
}
public PageDTO(String url, int currentPage, int totalCnt, List<T> list) {
super();
this.url = url;
this.currentPage = currentPage;
this.totalCnt = totalCnt;
this.totalPage = (int) Math.ceil((double)totalCnt/CNT_PER_PAGE);
this.startPage = (currentPage-1)/CNT_PER_PAGE_GROUP * CNT_PER_PAGE_GROUP + 1;
this.endPage = startPage + CNT_PER_PAGE_GROUP - 1;
if(endPage > totalPage) {
this.endPage = totalPage;
}
this.list = list;
System.out.println(totalPage + ":" + startPage + ":" + endPage);
}
public PageDTO(String url,
int currentPage,
int totalCnt,
int totalPage,
int startPage,
int endPage, List<T> list) {
super();
this.url = url;
this.currentPage = currentPage;
this.totalCnt = totalCnt;
this.totalPage = totalPage;
this.startPage = startPage;
this.endPage = endPage;
this.list = list;
}
// getter setter 는 알아서 추가
5. RepBoardController.java
- list() 수정
pageDTO
사용하기
@GetMapping(value= {"/list", "/list/{currentPage}"})
public Object list(@PathVariable Optional<Integer> currentPage) {
try {
PageDTO<RepBoard> pageDTO;
if(currentPage.isPresent()) { //currentPage값이 있는 경우
int cp = currentPage.get();
pageDTO = service.findAll(cp);
}else { //값이 없는 경우(null인 경우)
pageDTO = service.findAll();
}
return pageDTO;
}catch(FindException e) {
Map<String, Object> returnMap = new HashMap<>();
returnMap.put("msg", e.getMessage());
returnMap.put("status", 0);
return returnMap;
}
}
6. DAO, Service, Mapper 수정해 주기
- Mapper에 pageDTO에 필요한
findCount
추가됨- DAO에 Page 정보들
Map
으로 추가로 넣어주기- Service에 findAll할때 findCount도 같이 읽어오기
A) RepBoardMapper.xml
findCount 추가
<select id="findCount" resultType="int">
SELECT COUNT(*) FROM repboard
</select>
B) RepboardDAOOracle.java
- findAll() 수정 , findCount() 추가
- 인터페이스에도 추가 해주기
@Override
public List<RepBoard> findAll() throws FindException {
return findAll(1,10);
}
//인터페이스에 findAll 오버로딩 추가 해주기
@Override
public List<RepBoard> findAll(int crrPage, int cntPage) throws FindException {
SqlSession s = sqlSessionFactory.openSession();
try {
Map<String, Integer> page = new HashMap<String, Integer>();
page.put("currentPage", crrPage);
page.put("cntPerPage", cntPage);
List<RepBoard> list=
s.selectList("com.my.board.RepBoardMapper.findAll", page);
if(list == null || list.isEmpty()) {
throw new FindException();
}
return list;
} catch (Exception e) {
e.printStackTrace();
throw new FindException();
}finally {
if(s != null) {s.close();}
}
}
@Override
public int findCount() throws FindException {
SqlSession session = null;
try {
session = sqlSessionFactory.openSession();
return session.selectOne("com.my.board.RepBoardMapper.findCount");
}catch(Exception e) {
e.printStackTrace();
throw new FindException(e.getMessage());
}finally {
if(session != null) {
session.close();
}
}
}
C) RepboardService.java
- findAll() 수정
public PageDTO<RepBoard> findAll() throws FindException{
return findAll(1);
}
public PageDTO<RepBoard> findAll(int currentPage) throws FindException{
String url = "/board/list";
int totalCnt = dao.findCount();
List<RepBoard> list = dao.findAll(currentPage, PageDTO.CNT_PER_PAGE);
PageDTO<RepBoard> pageDTO = new PageDTO<>(url, currentPage, totalCnt, list);
return pageDTO;
}
스프링 목록
- Spring(1) - 백엔드 초기설정
- Spring(2) -스프링 Client 파일 업로드(1)
- Spring(3) -스프링 Client 파일 업로드(2)
- Spring(4) - 백엔드 RESTFULL 로 바꾸기
- Spring(5) - 게시판 페이징 기능 추가하기
- Spring(6) - 검색 기능 추가
- Spring(7) - 프론트 ContextPath 동적 설정
스프링 부트 목록