jnk1m
Foliage IT
jnk1m
전체 방문자
오늘
어제
  • 분류 전체보기 (209)
    • Today I Learned (34)
    • Java (47)
    • Database (15)
    • [NHN Academy] (27)
    • Spring (47)
    • HTML + CSS + JavaScript (11)
    • JSP (3)
    • Node.js (10)
    • React Native (2)
    • 기타 (8)
    • 스크랩 (5)

인기 글

최근 글

티스토리

hELLO · Designed By 정상우.
글쓰기 / 관리자
jnk1m

Foliage IT

Spring

[Spring] Day11 (Code): 페이징 처리

2022. 3. 31. 00:58

1. Criteria.java

package com.board.domain;

import org.springframework.web.util.UriComponentsBuilder;

import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

@Getter
@Setter
@ToString
public class Criteria { //페이징 처리시 부수적으로 필요한 정보들 담아줄 객체

	private int pageNum; //페이지 번호
	private int listQty; //한 페이지에 보여줄 개시물 개수 
	
	public Criteria() {
		this(1,10); //1 페이지 보여주게끔 
	}
	
	public Criteria (int pageNum, int listQty) {
		this.pageNum = pageNum;
		this.listQty = listQty;
	}
	
	// 파라미터 완성해서 돌려주는 메서드
	public String getParameterLink() {
		UriComponentsBuilder builder = UriComponentsBuilder.fromPath("")
				.queryParam("pageNum",this.pageNum)
				.queryParam("listQty", this.listQty);
		System.out.println("uri String: " + builder.toUriString());
		return builder.toUriString();
	}
	
}

 

2. PageDTO

package com.board.domain;

import lombok.Getter;
import lombok.ToString;

@Getter
@ToString
public class PageDTO { //전체 페이지 관리

	private int startPage;
	private int endPage;
	private boolean prev, next;
	
	private int total; //전체 글 개수
	private Criteria cri; //페이지 번호, 페이지 당 보여줄 글의 개수 
	
	public PageDTO(Criteria cri, int total) { //좀 더 포괄적인 페이징 처리?..
		this.cri = cri;
		this.total = total;
		
		this.endPage = (int)(Math.ceil(cri.getPageNum()/10.0)) * 10; //10
		this.startPage = this.endPage - 9; //-9
		int lastPage= (int)(Math.ceil((total*1.0)/cri.getListQty())); //한페이지에 10개씩 보여줄거야
		if(lastPage < this.endPage) {
			this.endPage = lastPage;
		}
		
		this.prev=this.startPage > 1;
		this.next=this.endPage < lastPage;
	}
}

 

3. 글 목록 페이징 추가 버전

//글 목록 (페이징 처리 추가)
	@GetMapping("list") //list 요청 시 pageNum, listQty가 들어와야 함. 
	public void list(Criteria cri, Model model) {
		//페이징처리 버전
		//현재 페이지 번호에 따른, 보여줄 글 목록을 가져와 view에 전달
		model.addAttribute("list", boardService.getList(cri));
		
		//전체 글의 개수 가져오고 
		int total = boardService.getTotal();
		//화면에 띄워줄 페이지 번호 등 계산 완료된 pageDTO 객체도 view 전달
		model.addAttribute("pageMaker", new PageDTO(cri, total));
		//http://localhost:8080/board/list?pageNum=1&listQty=3# 이런식으로 브라우저 입력

	}

controller

 

현재 페이지 번호에 따른, 보여줄 글 목록을 가져와 view에 전달 getList

//전체글 페이징 처리해서 가져오기
	public List<BoardVO> getList(Criteria cri);
    --------------------------------------------
    //이 밑은 serviceImpl
    	@Override
	public List<BoardVO> getList(Criteria cri) {
		System.out.println(cri);
		return boardMapper.getListWithPaging(cri);
	}

service

 

//페이징 처리해서 전체 글 가져오기 mapper.java
	public List<BoardVO> getListWithPaging(Criteria cri);
    -----------------------------------------------------
 <select id="getListWithPaging" resultType="boardVO">
      <![CDATA[
         select bno, title, content, writer, regdate, updatedate from
             (select rownum r, bno, title, content, writer, regdate, updatedate from 
                 (select /*+ INDEX_DESC(board pk_board)*/ 
                  bno, title, content, writer, regdate, updatedate 
                  from board) 
             where rownum <= #{pageNum} * #{listQty} ) 
         where r > (#{pageNum} - 1) * #{listQty}
      ]]>
   </select>

mapper

 

전체 글의 개수 가져오는 getTotal

//전체 글의 개수 가져오기
	public int getTotal();
    -------------------------
 //serviceImpl
 	@Override
	public int getTotal() {
		return boardMapper.getTotalCount();
	}

controller

 

//전체 글의 개수 가져오기
	public int getTotalCount();
----------------------------------
//mapper.xml
 <!-- 전체 글의 개수 가져오기 -->
   <select id="getTotalCount" resultType="int">
   	select count(*) from board
   </select>

mapper

 

<%@ page language="java" contentType="text/html; charset=UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>list</title>
  <link href="/resources/css/style.css" rel="stylesheet" type="text/css">
  <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
</head>
<body>
<br/>
<h1 align="center">게시판</h1>
<table>
	<tr>
		<td colspan="5" align="left">
			<button onclick="window.location='/board/write'">글 작성</button>
		</td>
	<tr> <!-- 위에 카테고리 안내 -->
		<td>No.</td>
		<td>제목</td>
		<td>작성자</td>
		<td>작성일</td>
		<td>수정일</td>
	</tr>	

<!-- board: BoardVO 객체 담기는 변수
items: 컨트롤러로부터 전달 받은 List<BoardVO> 리스트
list의 요소 개수만큼 자동으로 반복하며, 하나씩 꺼내서 board 변수에 채워줌
 -->
<c:forEach var="board" items="${list}">
	<tr> <!-- 글 리스트로 출력 -->
		<td>${board.bno}</td>
		<td align="left"><a class="move" href="${board.bno}">${board.title}</a></td>
		<td>${board.writer}</td>
		<td><fmt:formatDate value="${board.regdate}" pattern="yy-MM-dd HH:mm"/></td>
		<td><fmt:formatDate value="${board.updateDate}" pattern="yy-MM-dd HH:mm"/></td>
	</tr>	
</c:forEach>
</table>
<br/><br/>
<div align="center">
      <%-- previous --%>
      <c:if test="${pageMaker.prev}">
         <a class="paging_btn" href="${pageMaker.startPage-1}" style="color: #77878F">&lt; &nbsp;</a>
      </c:if>
   
      <%-- 페이지번호 --%>
      <c:forEach var="num" begin="${pageMaker.startPage}" end="${pageMaker.endPage}" >
          <a class="paging_btn" href="${num}" style="color: #77878F">&nbsp;${num}&nbsp;</a> 
      </c:forEach>
   
      <%-- next --%>
      <c:if test="${pageMaker.next}">
         <a class="paging_btn" href="${pageMaker.endPage+1}" style="color: #77878F">&nbsp; &gt;</a>
      </c:if>
   </div>
   <%--페이지 번호 누를 때 전송해줄 숨김 폼 태그  --%>
   <form action="/board/list" method="get" id="pagingForm">
   	<input type="hidden" name="pageNum" value="${pageMaker.cri.pageNum}"/>
   	<input type="hidden" name="listQty" value="${pageMaker.cri.listQty}"/>
   </form>
<br/><br/><br/><br/>


<script>
	$(document).ready(function(){

	//글 작성후 list로 리다이렉트 되었을 때 alert 띄워주기
	let result="${result}";
	checkResult(result); // alert 띄울지 말지 함수 호출
	
	//글 작성 처리 post -> 리스트로 이동 -> content로 갔다가 브라우저 뒤로하면 alert가 또 뜨기 때문에 수정해줌.
	//                     히스토리 삭제
	history.replaceState({},null,null);
	
	function checkResult(result){
		//result 값이 없거나 historu 기록이 없으면 그냥 함수 종료
		if(result=="" ||history.state){
			return;
		}
		//result 넘어와서 글 고유번호가 0보다 크면, alert 띄워라
		if(result == "success"){ // ==값이 같은 것, ===타입까지 같은 것 
			alert("요청 처리가 잘 처리되었습니다.")
		}else if(parseInt(result)>0){
			alert(result +"번 글이 등록 되었습니다.");
		}
	}//checkResult
	
	//숨김 폼태그 가져오기
	let pagingForm = $("#pagingForm");
	$(".paging_btn").click(function(e){ //e가 a태그 객체를 가리키게 됨.
		e.preventDefault(); //a 태그의 기본 기능 없애기
		console.log("a 클릭!" + e);
		//폼태그에서 name 속성이 pageNum인 input 태그를 찾아 input tag의 값을 클릭한 a 태그의 href 속성 값으로 변경
		//<input value=a의 href값
		pagingForm.find("input[name='pageNum']").val($(this).attr("href"));
		pagingForm.submit(); //submit 버튼 누른 것과 동일한 효과. 
	}); //paging_btn click
	
	//게시글 제목 클릭 시, content 페이지로 이동 처리
	$(".move").click(function(e){
		e.preventDefault();
		//숨김 폼 태그에 bno input hidden으로 태그 추가 
		pagingForm.append("<input type='hidden' name='bno' value='"+ $(this).attr("href") + "' />");
		//폼의 action 속성 값 (이동할 주소) content로 변경
		pagingForm.attr("action", "/board/content")
		pagingForm.submit(); //서브밋! 이동!
	})
	
	
	
	}); //ready
	
	
</script>
</body>
</html>

list.jsp

 

4. content, modify, delete 

//조회 폼
	@GetMapping({"content","modify","delete"})
	public void content(@RequestParam("bno") Long bno,@ModelAttribute("cri") Criteria cri , Model model) {
		model.addAttribute("board",boardService.get(bno));
	}
	
	//조회 처리
	@PostMapping("modify")
	public String modify(BoardVO board, Criteria cri,RedirectAttributes rttr) {
		boolean res =boardService.modify(board);
		if(res) {
			rttr.addFlashAttribute("result","success");
			System.out.println("수정 완료");
		}
		else System.out.println("수정 불가");
		return "redirect:/board/list" + cri.getParameterLink();
	}
	
	@PostMapping("delete")
	public String delete(@RequestParam("bno") Long bno,Criteria cri, RedirectAttributes rttr) {
		
		if(boardService.remove(bno)){
			rttr.addFlashAttribute("result","success");
		}
		
		return "redirect:/board/list"+ cri.getParameterLink();
	}

controller

 

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Content</title>
<link href="/resources/css/style.css" rel="stylesheet" type="text/css">
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
</head>
<body>
<br/>
<h1 align="center">Content</h1>
<table>
	<tr>
		<td>글 번호</td>
		<td>${board.bno}</td>
	</tr>
	<tr>
		<td>제목</td>
		<td>${board.title}</td>
	</tr>
	<tr>
		<td>작성자</td>
		<td>${board.writer}</td>
	</tr>
	<tr>
		<td>내용</td>
		<td><textarea rows="10" cols="30" disabled>${board.content}</textarea></td>
	</tr>
	<tr>
		<td>작성일</td>
		<td><fmt:formatDate value="${board.regdate}" pattern="yyyy-MM-dd HH:mm"/></td>
	</tr>
	<tr>
		<td>수정일</td>
		<td><fmt:formatDate value="${board.updateDate}" pattern="yyyy-MM-dd HH:mm"/></td>
	</tr>
	<tr>
		<td colspan="2">
			<button class="btn" data-oper="modify" >수정</button> <!-- 하이픈 뒤에 이름은 우리가 변수 만들 듯이 지어주면 됨. 여기선 oper -->
			<button class="btn" data-oper="delete">삭제</button>
			<button class="btn" data-oper="list">리스트</button>
			
		</td>
	</tr>
</table>
<form action="/board/modify" method="get" >
	<input type="hidden" name="bno" value="${board.bno}"/>
	<input type="hidden" name="pageNum" value="${cri.pageNum}"/>
	<input type="hidden" name="listQty" value="${cri.listQty}"/>
</form>

<script>
$(document).ready(function(){
	//숨김 폼태그 가져오기
	let formObj = $("form");
	$("button.btn").click(function(e){
		e.preventDefault();
		let operation = $(this).data("oper");
		
		if(operation === 'delete'){
			formObj.attr("action", "/board/delete")
		}else if(operation === 'list'){
			formObj.attr("action","/board/list");
		}
		formObj.submit(); //이동
	});
	
	
	
	
});

</script>
</body>
</html>

content.jsp

 

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
        <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>modify</title>
<link href="/resources/css/style.css" rel="stylesheet" type="text/css">
</head>
<body>
<br/>   
   <h1 align="center"> 글 수정 </h1>
   <form action="/board/modify" method="post">
   <input type="hidden" name="pageNum" value="${cri.pageNum}"/>
   <input type="hidden" name="listQty" value="${cri.listQty}"/>
      <table>
      	<tr>
            <td>글 번호</td>
            <td><input type="text" name="bno" value="${board.bno}" readonly = "readonly"/></td>
            <%--<td><input type="text" name="title" value='<c:out value=${board.bno}"/> 이게 더 보안이 좋음 --%>
         </tr> 
         <tr>
            <td>제목</td>
            <td><input type="text" name="title"  value="${board.title}"  /></td>
         </tr>      
         <tr>
            <td>내용</td>
            <td><textarea rows="10" cols="30" name="content">${board.content}</textarea></td>
         </tr>      
         <tr>
            <td>작성자</td>
            <td><input type="text" name="writer"  value="${board.writer}" /></td>
         </tr>
         <tr>
			<td>작성일</td>
			<td><fmt:formatDate value="${board.regdate}" pattern="yyyy-MM-dd HH:MM"/></td>
		</tr>
		<tr>
			<td>수정일</td>
			<td><fmt:formatDate value="${board.updateDate}" pattern="yyyy-MM-dd HH:MM"/></td>
		</tr>      
         <tr>
            <td colspan="2">
               <input type="submit" value="수정" />
               <input type="button" value="리스트" onclick="window.location='/board/list?pageNum=${cri.pageNum}&listQty=${cri.listQty}'"/>
            </td>
         </tr>      
      </table>
   </form>
</body>
</html>

modify

 

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>delete</title>
<link href="/resources/css/style.css" rel="stylesheet" type="text/css">
</head>
<body>
	<br/>
	<h1> 게시글 삭제</h1>
	<form action="/board/delete" method="post">
	<table>
		<tr>
			<td> [ #${board.bno}. ${board.title} ] <br />
			이 게시글을 삭제 하시겠습니까? <br/>
				 <input type="hidden" name="bno" value="${board.bno}" />
               <input type="hidden" name="pageNum" value="${cri.pageNum}" />
               <input type="hidden" name="listQty" value="${cri.listQty}" />

				<input type="submit" value="삭제 확인"/>
				<input type="button" value="취소" onclick="history.back()"/>
			</td>
			
		</tr>
	</table>
	</form>
	
	
	
</body>
</html>

delete.jsp

 

    'Spring' 카테고리의 다른 글
    • [Spring] Day12 (Code1): 게시물 검색
    • [Spring] Day12 (Note): 게시판 검색, REST
    • [Spring] Day11 (Note): 페이징 처리
    • [Spring] Day10 (Code)

    티스토리툴바