[Spring]게시판 만들기(페이징 처리)

dh·2022년 11월 22일
0

구디샵 프로젝트

목록 보기
1/5

프로젝트를 진행하며 맡은 게시판만드는법을 정리해보겠습니다.
먼저 게시판테이블에 들어갈 속성을 담을 NoticeVO 클래스를 만듭니다.

noticeVO

@Data
public class NoticeVO  {
	private Long noticeNum;
	private String id;
	private String title;
	private String contents;
	private Date regDate;
	private Long hit;
}

그리고 게시판 목록을 가져올 sql을 작성해야 되는데 pagination을 이용해 게시판의 페이지 이동을 하기 위해 Pager Class를 만듭니다.

Pager Class

@Data
@Slf4j
public class Pager {
	private Long page;	// 현재 게시판 페이지
	private Long perPage;	// 페이지당 글의 갯수
	private Long totalPage;	// 전체 페이지의 갯수
	private Long startRow;	// 현재 페이지의 시작 글번호
	private Long lastRow;	// 현재 페이지의 마지막 글번호
	private Long block;		// 현재 pagionation
	private Long perBlock;	// pagination당 page갯수
	private Long startNum;	// pagination의 시작 페이지번호
	private Long lastNum;	// pagination의 마지막 페이지번호
	private boolean pre;	// 이전페이지
	private boolean next;	// 다음페이지
	
	public Pager() {
		this.page=1L;
		this.perPage=10L;
		this.perBlock=10L;
	}
	
	public void setRow() {
    	//한페이지에 10개씩 출력 기준
		//page	startrow	lastrow
		//1		1			10
		//2		11			20
		//3		21			30
		this.startRow =  (this.getPage()-1)*this.getPerPage();
		this.lastRow = this.getPage()*this.getPerPage();
	}
	
	public void setNum(Long totalCount) {
    	// 게시판 글의 총 갯수로 전체페이지의 수를 구함
		this.totalPage = totalCount%this.getPerPage()==0 ? totalCount/this.getPerPage() : totalCount/this.getPerPage()+1;
        // 전체 페이지수로 전체블록의 수를 구함
		Long totalBlock = totalPage%this.getPerBlock()==0 ? totalPage/this.getPerBlock() : totalPage/this.getPerBlock()+1;
        
		/* 현재페이지에 해당하는 현재블록을 구함
          page	curBlcok
		 	1		1
		 	2		1
		 	3		1
		 	4		1
		 	5		1
		 	6		2*/
		Long curBlock = this.getPage()%this.getPerBlock()==0 ? this.getPage()/this.getPerBlock() : this.getPage()/this.getPerBlock()+1; 
		
        /* 현재블록의 startNum, lastNum을 구함
	 	curBlock	startNum	lastNum
	 	1			1			5
	 	2			6			10
	 	3			11			16
		*/
		this.startNum= (curBlock-1)*this.getPerBlock() + 1;
		this.lastNum= curBlock*this.getPerBlock();
		
        //현재블록이 마지막블록이면 lastNum은 마지막페이지번호임
		if(curBlock==totalBlock) {
			this.lastNum=totalPage;
		}
        // 2번 페이지이상 부터 이전버튼 활성화
		if(this.page>1) {
			pre=true;
		}else{
			pre=false;
		}
		//현재블록이 마지막블록보다 작으면 다음버튼 활성화
		if(curBlock<totalBlock) {
			next=true;
		}else{
			next=false;
		}
		
	}

	public Long getPerPage() {
		if(this.perPage==null) {
			this.perPage=10L;
		}
		return perPage;
	}
	
    // 페이지가 null이거나 음수이면 1로 초기화 (사용자가 임의로 페이지에 이상한 값을 입력해서 이동을 방지)
	public Long getPage() {
		if(this.page==null || this.page<=0) {
			this.page=1L;
		}
		return page;
	}
	
}

NoticeMapper에 게시판목록을 가져오는 sql을 mapper에 등록합니다. mysql의 limit을 사용하여 startRow번호 부터 perPage개씩 목록을 가져옵니다. mysql은 0번부터 시작하고 oracle은 rownum을 사용할때 1번 부터 시작하는 것 같습니다.

NoticeMapper.xml

<select id="getList" parameterType="Pager" resultType="NoticeVO" >
		SELECT * FROM NOTICE ORDER BY NOTICENUM DESC LIMIT #{startRow},#{perPage} 
</select>

// 전체 글의 갯수
<select id="getTotalCount" resultType="Long">
		SELECT COUNT(NOTICENUM) FROM NOTICE
</select>

// 오라클에서 사용할때
SELECT NUM,TITLE,WRITER,REGDATE,HIT 
FROM (SELECT ROWNUM R, N.* FROM
		(SELECT * FROM NOTICE ORDER BY NUM DESC) N)
WHERE R BETWEEN #{startRow} AND #{lastRow}

NoticeMapper.java에 등록하고 NoticeService에서 페이지번호를 세팅합니다.

NoticeService

@Autowired
private NoticeMapper noticeMapper;
    
public List<NoticeVO> getList(Pager pager)throws Exception{
		Long totalCount = noticeMapper.getTotalCount();
		pager.setRow();
		pager.setNum(totalCount);
		
		return noticeMapper.getList(pager);
	};

컨트롤러에서 리스트와 페이지정보를 넘겨줍니다.

Controller

	@GetMapping("notice")
	public ModelAndView getBoard(Pager pager)throws Exception {
		ModelAndView mv = new ModelAndView();
		
		List<NoticeVO> list = noticeService.getList(pager);

		mv.addObject("list",list);
		mv.addObject("pager",pager);
		mv.setViewName("/board/notice");
		return mv;
	}

patgination은 bootstrap으로 만들었습니다. 게시글의 상세정보를 보기위해 noticeNum을 넘겨 주는 링크를 제목에 걸어줍니다.

notice.jsp

<table class="table table-hover" id="list">
    <tr>
      <th>번호</th>
      <th>제목</th>
      <th>작성자</th>
      <th>날짜</th>
      <th>조회수</th>
    </tr>
    <c:forEach items="${list}" var="noticeVO">
      <tr>
        <td>${noticeVO.noticeNum}</td>
        <td><a href="./detail?noticeNum=${noticeVO.noticeNum}">${noticeVO.title}</a></td>
        <td>${noticeVO.id}</td>
        <td>${noticeVO.regDate}</td>
        <td>${noticeVO.hit}</td>							
      </tr>	            	
    </c:forEach>
</table>

<div>
   <nav aria-label="Page navigation example">
      <ul class="pagination">
         <li class="page-item"  value="${pager.pre}" id="pre">
           <a class="page-link" href="./notice?page=${pager.page-1}" aria-label="Previous">
             <span aria-hidden="true">&laquo;</span>
           </a>
         </li>
  
         <c:forEach var="i" begin="${pager.startNum}" end="${pager.lastNum}">
            <li class="page-item ${pager.page==i? 'active':''}">
                <a class="page-link" href="./notice?page=${i}">${i}</a>
             </li>
         </c:forEach>
                    
         <li class="page-item ${pager.next?'':'disabled'}" id="next">
             <a class="page-link" href="./notice?page=${pager.page+1}" aria-label="Next">
                <span aria-hidden="true">&raquo;</span>
              </a>
          </li>
       </ul>
    </nav>
</div>

0개의 댓글