[Springboot] 댓글 게시판 #2 (페이징)

728x90

🔔 TODO :  페이징 , 게시글  AJax수정, 삭제  

📘 project : 인텔리제이 - SpringBootMybatisMini

github : https://github.com/Hyeonqz/SpringBootMybatisMini


 

스프링부트 동작관정 간단
  1. 클라이언트가 JSP 페이지에 데이터를 입력하고 제출합니다.
  2. JSP 페이지에서 컨트롤러에게 요청을 보냅니다.
  3. 컨트롤러는 요청을 받고 필요한 작업을 수행합니다.
  4. 컨트롤러는 서비스로 데이터 처리를 위임합니다.
  5. 서비스는 필요한 비즈니스 로직을 실행하고 데이터베이스에서 데이터를 가져옵니다.
  6. 서비스가 데이터 처리를 완료하면, 결과를 컨트롤러로 반환합니다.
  7. 컨트롤러는 JSP 페이지로 데이터를 전달합니다.
  8. JSP 페이지는 데이터를 이용하여 동적 웹 페이지를 생성하고 클라이언트에게 반환합니다.

따라서 데이터 처리 후 반환되는 곳은  컨트롤러이다.

 

 

페이징을 해보겠습니다. 

 

1) mapper 

    <select id="getList" parameterType="HashMap" resultType="MemboardDto">
        select * from memboard order by num desc limit #{start},#{perpage}
    </select>
  • mysql -> limit 를 알아야지 페이징을 할 수 있습니다.
    • limit는 (begin, end)로 구성되며 (시작페이지부터, 마지막 페이지) 즉 내가 설정해둔 시작페이지부터 내가설정해둔 마지막페이지 까지 제한 한다는 뜻 입니다. 

 

 

2) service

	@Override
	public List<MemBoardDto> getList(int start, int perpage) {
		HashMap<String,Integer> map = new HashMap<>();
		map.put("start",start);
		map.put("perpage",perpage);

		return memBoardMapperInter.getList(map);
	}
  • 페이징을 하기 위해서 Map 컬렉션에 start, perpage를 담아서 dto값 , map을 list에 리턴합니다 

 

3) controller 

	@GetMapping("/list")
	public ModelAndView goreboard(
		@RequestParam(value="currentPage",defaultValue = "1") int currentPage) {
		ModelAndView mv= new ModelAndView();

		int totalCount = memboardService.getTotalCount();

		//페이징 처리 필요한 변수 선언
		int totalPage; //총 페이지수
		int startPage; //각블럭에서 보여질 시작페이지
		int endPage; //각블럭에서 보여질 끝페이지
		int startNum; //db에서 가져올 글의 시작번호(mysql은 첫글이 0,오라클은 1)
		int perPage=10; //한페이지당 보여질 글의 갯수
		int perBlock=5; //한블럭당 보여질 페이지 개수

		//현재페이지 읽기(단 null일경우는 1페이로 준다)계산을 해야하므로 int로 형변환해줌
		//if(("currentPage")==null)
		//	currentPage=1;
		//else
		//currentPage=Integer.parseInt(("currentPage"));

		//총페이지수 구하기
		//총글의 갯수/한페이지당 보여질 개수로 나눔(7/5=1)
		//나머지가 1이라도 있으면 무조건 1페이지 추가(1+1=2페이지가 필요)
		totalPage=totalCount/perPage+(totalCount%perPage==0?0:1);

		//각블럭당 보여야할 시작페이지
		//perBlock=5일경우는 현재페이지 1~5 시작:1 끝:5
		//현재페이지 13  시작:11  끝:15
		startPage=(currentPage-1)/perBlock*perBlock+1;

		endPage=startPage+perBlock-1;

		// 총페이지가 23일경우 마지막블럭은 25가아니라 23이다
		if(endPage>totalPage)
			endPage=totalPage;

		//각페이지에서 보여질 시작번호
		//1페이지: 0,2페이지:5 3페이지:10....
		startNum=(currentPage-1)*perPage;

		//각 페이지에서 필요한 게시글 가져오기 == 보여질 글만 가져오기
		//각페이지당 출력할 시작번호 구하기 no
		//총글개수가 23이면 1페이지 23,2페이지는 18,3페이지 13.....
		//출력시 1씩 감소하며 출력
		List<MemBoardDto> list = memboardService.getList(startNum, perPage);

		//list의 각 글에 댓글 개수 표시를 해야함
		/*for(MemBoardDto m:list) {
			m.setAcount(adao.getAnswerList(d.getNum()).size());
		}*/

		//각 페이지에 출력할 시작번호
		int no = totalCount-(currentPage-1)*perPage;

		mv.addObject("totalCount",totalCount);
		mv.addObject("list",list);
		mv.addObject("startPage",startPage);
		mv.addObject("totalPage",totalPage);
		mv.addObject("endPage",endPage);
		mv.addObject("no",no);
		mv.addObject("currentPage",currentPage);

		mv.setViewName("/memboard/memlist");

		return mv;
	}
  • form 에 보낼 때, 보내줄 값이 많기 때문에 ModelandView를 리턴타입으로 사용해서 보내준다.
  • totalCount는 모든 dto들을 list로 출력하기 위해서 생성한 변수 이다.
  • 그리고 페이징 처리에 필요한 변수들을 미리 선언해줍니다
    • 자세한 설명들은 코드에 주석으로 설명되어 있습니다. 
  • 그리고 컨트롤러에서 addObject 메소드 안에있는 key값들은 jsp파일에서 직접적으로 사용할 수 있습니다.

 

4) form 작성

<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.1/font/bootstrap-icons.css">
  <link href="https://fonts.googleapis.com/css2?family=VT323&display=swap" rel="stylesheet">
  <script src="https://code.jquery.com/jquery-3.7.0.js"></script>
  <title>회원 게시판</title>
</head>
<body>
<div style="width: 1150px;">
<c:if test="${sessionScope.loginok != null}">
<button type="button" class="btn btn-outline-info" onclick="location.href='form'" style="width:100px;">글쓰기</button>
</c:if>
<br><br>
<table class="table table-bordered">
  <tr class="table-secondary" align="center">
    <th width="60">번호</th>
    <th width="60">제목</th>
    <th width="60">작성자</th>
    <th width="60">조회수</th>
    <th width="60">등록일</th>
  </tr>

  <c:if test="${totalCount==0}">
    <tr>
      <td>등록된 글이 없습니다.</td>
    </tr>
  </c:if>


  <c:if test="${totalCount>0 }">
    <c:forEach var="dto" items="${list }" varStatus="i">
      <tr>
        <td align="center">${no }</td>
        <c:set var="no" value="${no-1 }"/> <!-- 출력 후 감소시키기  -->
        <td> <!-- 제목 -->

          <!-- 제목.. 여기 누르면 내용 보기로 -->
          <a href="content?num=${dto.num }&currentPage=${currentPage}">${dto.subject }</a>

          <!-- 사진이 있을 경우 아이콘 표시 -->
          <c:if test="${dto.uploadfile != 'no' }">
            <i class="bi bi-image"></i>
          </c:if>
        </td>

        <td><fmt:formatDate value="${dto.writeday }" pattern="yyyy-MM-dd"/></td>
        <td align="center">${dto.readcount }</td>
      </tr>
    </c:forEach>
  </c:if>
</table>

  <!-- 페이지번호 출력 -->


  <!-- 페이지 번호 출력 -->
  <div>
    <!-- 페이지 번호 출력 -->
    <c:if test="${totalCount>0 }">
      <div style="width: 800px; text-align: center">
        <ul class="pagination justify-content-center">
          <!-- 이전 -->
          <c:if test="${startPage>1 }">
            <li class="page-item"><a class="page-link" href="list?currentPage=${startPage-1 }">이전</a></li>
          </c:if>

          <c:forEach var="pp" begin="${startPage }" end="${endPage }">
            <c:if test="${currentPage==pp }">
              <li class="page-item active"><a class="page-link"
                                              href="list?currentPage=${pp }">${pp }</a></li>
            </c:if>
            <c:if test="${currentPage!=pp }">
              <li class="page-item"><a class="page-link" href="list?currentPage=${pp }">${pp }</a></li>
            </c:if>
          </c:forEach>

          <!-- 다음 -->
          <c:if test="${endPage<totalPage }">
            <li class="page-item"><a class="page-link"
                                     href="list?currentPage=${endPage+1 }">다음</a></li>
          </c:if>

        </ul>
      </div>
    </c:if>
  </div>

</div>

</table>
</div>
</body>
</html>

 

  • totalCount -> 즉 글의 개수가 없으면, 글이 없습니다. 라고 뜨고, totalCount 1 이상있으면 리스트로 나열한다.
  • JSTL 태그를 사용해서, c:for each문을 사용해서 list를 출력해줍니다.

 

지적 감사하게 받겠습니다

728x90