페이징 까지 구현했으니 이제 중요한 기능중에 하나인 검색 기능을 추가하겠습니다.

저희는 페이징 처리하는 부분에서 많은 기능들을 처리하였는데요~

Criteria, PageMaker VO에서 makeQuery 메서드 기억하시나요?

makeQuery 부분에 두 가지 속성을 추가하겠습니다!

 

- searchType : 검색 타입

 

- keyword : 검색어

 

이제 구현해보겠습니다!

 

Criteria, PageMaker 수정

 

검색을 했을 때 검색 결과에 따른 정보를 게시물을 삭제, 등록, 수정, 조회 후에도 그대로 유지하려면 

URI에 searchType, keyword를 달고 다녀야합니다! 

페이징처리에서 사용했던 page와 perPageNum처럼요!

 

package kr.co.web.domain;

import org.springframework.web.util.UriComponents;
import org.springframework.web.util.UriComponentsBuilder;

public class Criteria {
	
	private int page;
	private int perPageNum;
	private String searchType;
	private String keyword;
	
	public Criteria() {
		// TODO Auto-generated constructor stub
		this.page = 1;
		this.perPageNum = 10;
		this.searchType = null;
		this.keyword = null;
	}
    
        // getter, setter 생략
	
	public String makeQuery() {
		UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.newInstance()
				.queryParam("page", this.page)
				.queryParam("perPageNum", this.perPageNum);
		
		if(searchType != null) {
			uriComponentsBuilder
				.queryParam("searchType", this.searchType)
				.queryParam("keyword", this.keyword);
		}
		return uriComponentsBuilder.build().encode().toString();
	}
	
	@Override
	public String toString() {
		return "Criteria [page=" + page + ", perPageNum=" + perPageNum + "]";
	}
	
	
}

 

 

makeQuery메서드에서 if(searchType != null) 이게 조건을 준 이유는요

사용자가 검색을 하지도 않았는데 굳이 searchType과 keyword를 가지고 갈 필요가 없기때문에 조건을 주었습니다.

 

PageMaker의 makeQuery도 수정하겠습니다!

 

package kr.co.web.domain;

import org.springframework.web.util.UriComponents;
import org.springframework.web.util.UriComponentsBuilder;

public class PageMaker {
	
	private int displayPageCnt = 10; // 화면에 보여질 페이지 번호 수
	private int totalDataCount; // 실제 게시물 수
	private int startPage; // 현재 페이지 기준 시작 페이지 번호 
	private int endPage; // 현재 페이지 기준 끝 페이지 번호
	private boolean prev; // 이전 버튼 활성화 여부
	private boolean next; // 다음 버튼 활성화 여부
	private Criteria cri; //page(현재 페이지), perPageNum(페이지 당 보여질 게시물의 수)
	private int finalPage; // 맨끝
	private int firstPage; // 맨처음
	
	public PageMaker(Criteria cri) {
		this.cri = cri;
	}
	
	
	public int getDisplayPageCnt() {
		return displayPageCnt;
	}
	
	public void setDisplayPageCnt(int displayPageCnt) {
		this.displayPageCnt = displayPageCnt;
	}
	
	public int getTotalDataCount() {
		return totalDataCount;
	}

	public void setTotalDataCount(int totalDataCount) {
		this.totalDataCount = totalDataCount;
		calcData();
	}
	
	//startPagem endPage, prev, next, firstPagem finalPage 계산
	public void calcData() {
		int page = this.cri.getPage();
		int perPageNum = this.cri.getPerPageNum();
		
		// 현재 페이지가 2면 2/10 = 0.2 Math.ceil객체를 이용하여 무조건 올림 하면 1 * displayPageCnt = 10
		this.endPage = (int)(Math.ceil(page / (double)displayPageCnt) * displayPageCnt);
		
		// endPage - 화면에 보여줄 페이지수를 한뒤 + 1을 하면 된다. 
		this.startPage = (this.endPage - displayPageCnt) + 1;
		
		// 전체 게시물 수를 통한 endPage 
		// 데이터가 89 개면 9페이지까지 출력
		int tempEndPage = (int)(Math.ceil(totalDataCount / (double)perPageNum));
		
		if(this.endPage > tempEndPage) {
			this.endPage = tempEndPage;
		}
		
		this.prev = startPage == 1? false : true;
		this.next = (endPage * perPageNum) <= totalDataCount ? true : false;
		
		// 맨끝
		// +1하는 이유는 저렇게 계산하면 맨끝에서 2번째 페이지가 출력되기때문.
		this.finalPage = (int)(Math.ceil(totalDataCount / perPageNum)+1);
						
		// 맨처음
		this.firstPage = 1;
	}
	
	public String makeQuery(int page) {
		UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.newInstance()
				.queryParam("page", page)
				.queryParam("perPageNum", this.cri.getPerPageNum());
		
		if(this.cri.getSearchType() != null) {
			uriComponentsBuilder
				.queryParam("searchType", this.cri.getSearchType())
				.queryParam("keyword", this.cri.getKeyword());
		}
		return uriComponentsBuilder.build().encode().toString();
	}
	
	
	
}

 

 

boardMapper.xml 수정

 

검색을 하기 위해 다음과 같이 select 박스를 구현하겠습니다.

 

 

listPage.jsp

<div class="container">
	<select id="searchTypeSel" name="searchType">
		<option value="">검색조건</option>
		<option value="t">제목</option>
		<option value="c">내용</option>
		<option value="w">작성자</option>
		<option value="tc">제목+내용</option>
		<option value="all">전체조건</option>
	</select>
		
	<input type="text" id="keyword" name="keyword" value="${pageMaker.cri.keyword}" placeholder="검색어를 입력하세요"/>
	<button id="searchBtn" class="btn btn-primary">검색</button>
</div>

 

 

만약 제목에 슥이 라는 게시물을 검색하려면 다음과 같이 쿼리문을 작성하여 mysql 서버에 있는 blog 테이블에서 데이터를 조회해와야 합니다.

 

select *
from board
where title like CONCAT ('%', '슥이', '%')
order by board_number desc, create_date desc
limit #{dataStart}, #{perPageNum}

 

이렇게 검색의 타입마다 쿼리문을 작성하려면 복잡하기도 하고 노가다 입니다.

이럴 때 MyBatis에서 제공하는 if문을 사용하면 검색 조건에 따른 동적 sql문을 손쉽게 추가해줄 수 있습니다.

 

기존의 listPage 쿼리를 수정해보겠습니다.

 

<!-- board 페이징 조회 -->
	<select id="listPage" resultType="BoardVO">
		select *
		from board
		<if test="searchType != null">
		
			<if test="searchType == 't'.toString()">
				where title like CONCAT('%', #{keyword}, '%')
			</if>
			
			<if test="searchType == 'c'.toString()">
				where contents like CONCAT('%', #{keyword}, '%')
			</if>
			
			<if test="searchType == 'w'.toString()">
				where name like CONCAT('%', #{keyword}, '%')
			</if>
			
			<if test="searchType == 'all'.toString()">
				where title like CONCAT('%', #{keyword}, '%')
					or contents like CONCAT('%', #{keyword}, '%')
					or name like CONCAT('%', #{keyword}, '%')
			</if>
			
		</if>
		order by board_number desc, create_date desc
		limit #{dataStart}, #{perPageNum}
	</select>

 

이렇게 작성했는데 생각해보니 검색된 결과에 따라 페이지 번호도 달라지기 때문에 전체 게시물 수를 구하는

totalCount 쿼리도 수정해주어야 하는데 위와 같이 추가하기에는 코드가 중복이 되기 때문에

<sql>과 <include>를 사용하겠습니다.

 

<sql>이란 쉽게 설명을 하자면 원터치 텐트라고 생각하시면 됩니다.

<include>는 원터치 텐트를 던지면 알아서 텐트가 쳐지듯이 include태그를 작성하면 펴진다 라고 이해하시면 됩니다!

 

<!-- 검색 -->
	<sql id="searchCondition">
		<if test="searchType != null">
		
			<if test="searchType == 't'.toString()">
				where title like CONCAT('%', #{keyword}, '%')
			</if>
			
			<if test="searchType == 'c'.toString()">
				where contents like CONCAT('%', #{keyword}, '%')
			</if>
			
			<if test="searchType == 'w'.toString()">
				where name like CONCAT('%', #{keyword}, '%')
			</if>
			
			<if test="searchType == 'all'.toString()">
				where title like CONCAT('%', #{keyword}, '%')
					or contents like CONCAT('%', #{keyword}, '%')
					or name like CONCAT('%', #{keyword}, '%')
			</if>
			
		</if>
	</sql>
	
	<!-- board 페이징 조회 -->
	<select id="listPage" resultType="BoardVO">
		select *
		from board
		<include refid="searchCondition"></include>
		order by board_number desc, create_date desc
		limit #{dataStart}, #{perPageNum}
	</select>
    
    <!-- 전체 데이터 구하기 -->
	<select id="totalCount" resultType="int">
		select count(board_number)
		from board
		<include refid="searchCondition"></include>
	</select>

 

그리고 boardDAO의 listPage 메서드와 totalCount 메서드 둘 다 Criteria를 매개변수로 받았기 때문에

boardMapper까지 searchType과 keyword가 무사히 전달된 것입니다.

'JAVA > blog' 카테고리의 다른 글

jQuery .val() - form의 값을 가져거나 값을 설정하는 메서드  (0) 2020.07.23
검색(2)  (0) 2020.07.23
페이징 처리(5)  (0) 2020.07.19
페이징 처리(4)  (0) 2020.07.16
페이지 처리(3)  (0) 2020.07.16

지금 까지 페이징 기능을 구현했는데요

페이징 처리(3)에서 페이지 유지기능 구현을 위해 uriComponents를 만들었는데

이제 페이지 유지기능을 만들어 보도록 하겠습니다.

 

페이지 유지기능이란 ?

 

보통의 게시판의 경우 상세보기에서 목록을 누르면 1페이지로 이동이 되는데

페이지 유지기능을 적용시키면 3페이지에서 상세보기를 한 후 목록 버튼을 누르면

1페이지로 가지 않고 3페이지 그대로 유지하는 기능입니다! 

 

조회 후 현재 페이지 정보 유지

 

3페이지에 있는 글을 읽고 현재 페이지를 유지하도록 구현할건데요

정보가 유지 되려면 URI에 page와 perPageNum의 값이 계속 유지되어야 하는데요

유지하도록 하기 위해 BoardController의 read 메소드의 매개변수에 Criteria를 추가해줍니다!

 

<!-- BoardController.java -->

@RequestMapping(value = "/read", method = RequestMethod.GET)
public void read(@RequestParam("board_number") Integer board_number, @ModelAttribute("cri") Criteria cri, Model model) throws Exception{
	 // 페이지 목록 유지를 위해 사용되고 있는 page, perPageNum 값 가져오기
	 logger.info("read GET!!!");
	 BoardVO board  = service.read(board_number);
	 model.addAttribute("BoardVO",board);
	 logger.info(board.toString());
	 System.out.println("vo 값 확인 :" + cri.getPage());
}

 

파라미터 값으로 @ModelAttribute("cri") Criteria cri 를 선언한 이유는

현재 페이지에 해당하는 page와 perPageNum을 데이터 전달 받기 위해서 입니다.

이렇게 사용하기 위해서는 VO에 변수를 선언하고, getter 와 setter를 생성해야 합니다!

파라미터에 선언 후 VO 데이터를 조회하려면

 

System.out.println("vo 값 확인 :" + cri.getPage());

 

이렇게 하게 되면 해당 VO인 Criteria의 값들을 가져 올 수 있습니다.

 

Controller를 수정해주었으니 이제 read.jsp도 수정 하도록 하겠습니다!

 

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>게시판</title>

	<script>
		var result = '${result}';
		if(result === 'updateOK') {
			alert("수정되었습니다.");
		}
	</script>
	
</head>
<body>
	
		<div>글번호 : ${BoardVO.board_number}</div>
	
		<div>
			<button><a href="/board/listPage${cri.makeQuery()}" class="btn btn-primary">목록</a></button>
			<button><a href="/board/update${cri.makeQuery()}&board_number=${BoardVO.board_number}" class="btn btn-warning">수정</a></button>
			<button><a href="/board/delete?board_number=${BoardVO.board_number}">삭제</a></button>
			
		</div>
		
		<div>
			<div>
				<label for="title">제목</label>
				<input type="text" id="title" name="title" value="${BoardVO.title}" readonly="readonly"/>		
			</div>
			
			<div>
				<label for="contents">내용</label>
				<textarea name="contents" id="contents" rows="3" readonly="readonly">${BoardVO.contents}</textarea>		
			</div>
			
			<div>
				<label for="name">작성자</label>
				<input type="text" name="name" id="name" value="${BoardVO.name}" readonly="readonly"/>		
			</div>
		</div>
		
		
		
</body>
</html>

 

이렇게 Controller와 read.jsp를 수정해주면 3페이지에서 글을 읽고 목록버튼을 누르면 1페이지로 가지 않고

3페이지를 유지하는 것을 볼 수 있습니다!

 

수정 후 현재 페이지 정보 유지

 

이제 수정 후에도 현재 페이지 정보를 유지하도록 할건데요

BoardController의 update 메서드를 수정하도록 하겠습니다.

 

@RequestMapping(value = "/update", method = RequestMethod.GET)
public void updateGET(@RequestParam("board_number") Integer board_number, @ModelAttribute("cri") Criteria cri, Model model) throws Exception {
	logger.info("updateGET!!!");
	BoardVO board  = service.read(board_number);
	 model.addAttribute("BoardVO",board);
}
	
@RequestMapping(value = "/update", method = RequestMethod.POST)
public String updatePOST(BoardVO board, Criteria cri, RedirectAttributes ra) throws Exception {
	logger.info("updateGET!!!");
	service.update(board);
	ra.addFlashAttribute("result", "updateOK");
	ra.addAttribute("page", cri.getPage());
	ra.addAttribute("perPageNum", cri.getPerPageNum());
	ra.addAttribute("board_number", board.getBoard_number());
	return "redirect:/board/read";
}

 

Controller를 수정했으니 update.jsp도 수정하도록 하겠습니다.

 

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>게시판</title>

</head>
<body>
	<form method="post">
		<div>글번호 : ${BoardVO.board_number}</div>
		<input type="hidden" name="board_number" value="${BoardVO.board_number}"/>
		
		<!-- page와 perPageNum  추가 -->
		<input type="hidden" name="page" value="${cri.page}" />
		<input type="hidden" name="perPageNum" value="${cri.perPageNum}" />
		
		<div>
			<div>
				<label for="title">제목</label>
				<input type="text" id="title" name="title" value="${BoardVO.title}"/>		
			</div>
			
			<div>
				<label for="contents">내용</label>
				<textarea name="contents" id="contents" rows="3">${BoardVO.contents}</textarea>		
			</div>
			
			<div>
				<label for="name">작성자</label>
				<input type="text" name="name" id="name" value="${BoardVO.name}" readonly="readonly"/>		
			</div>
		</div>
		
		<div>
			<button type="submit">등록</button>
			<button><a href="/board/read${cri.makeQuery()}&board_number=${BoardVO.board_number}" class="btn btn-danger">취소</a></button>
		</div>
	</form>
</body>
</html>

 

이렇게 코드를 수정 후 

실제로 수정하거나 취소 후 목록 버튼을 누르게 되면

1페이지로 가지 않고 3페이지면 3페이지를 유지하도록 적용했습니다.

 

삭제 후 현재 페이지 정보 유지

 

삭제 후에도 현재 페이지로 유지하려면 

BoardController의 delete 메서드를 수정 해야 합니다!

@RequestMapping(value = "/delete", method = RequestMethod.POST)
public String deletePOST(@RequestParam("board_number") Integer board_number, Criteria cri, RedirectAttributes ra) throws Exception {
	logger.info("deletePOST");
	service.delete(board_number);
	ra.addFlashAttribute("result", "deleteOK");
	ra.addAttribute("page", cri.getPage());
	ra.addAttribute("perPageNum", cri.getPerPageNum());
	logger.info("페이지 : " + cri.getPage());
	return "redirect:/board/listPage";
}

 

바뀐 점은 deletePOST 메서드의 매개변수에 Criteria VO를 추가하고 

addAttribute를 추가하여 listPage의 url에 붙도록 model 값을 보낸다!

 

 

'JAVA > blog' 카테고리의 다른 글

검색(2)  (0) 2020.07.23
검색 (1)  (0) 2020.07.23
페이징 처리(4)  (0) 2020.07.16
페이지 처리(3)  (0) 2020.07.16
페이징 처리(2)  (0) 2020.07.11

이제 본격적으로 Controller와 view단을 구현해보겠습니다.

- BoardController에 페이징 기능을 하는 listPage 메서드 추가

- listPage.jsp 생성

 

BoardController 수정

 

<!-- BoardController.java -->

@RequestMapping(value = "/listPage", method = RequestMethod.GET)
public void listPage(Criteria cri, Model model) throws Exception {
	logger.info("listPage!!!");
	List<BoardVO> boards = service.listPage(cri);
	model.addAttribute("list", boards);
	PageMaker pageMaker = new PageMaker(cri);
	int totalCount = service.totalCount(cri);
	pageMaker.setTotalDataCount(totalCount);
	model.addAttribute("pageMaker", pageMaker);
}

 

listPage 메서드에 의해 현재 페이지에 해당하는 게시물과 페이지번호를 나타내는 클래스인

PageMaker가 모델에 담겨 listPage.jsp로 전달됩니다.

 

<!-- listPage.jsp -->

<%@ 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">
<title>Insert title here</title>

	<script>
		var register = "${register}";
		if(register === "registerOK") {
			alert("등록 되었습니다.");
		}
		
		var result = "${result}";
		if(result === "deleteOK") {
			alert("삭제 되었습니다.");
		}
	</script>
	
		

</head>
<body>
	<div>
		<a href="/board/register"><button>새글 작성</button></a>
	</div>
	
	
	<table>
		<tr> <!-- 한줄 -->
			<th>번호</th> <!-- 첫번째 칸 -->
			<th>제목</th> <!-- 두번째 칸 -->
			<th>작성자</th> <!-- 세번째 칸 -->
			<th>작성일자</th> <!-- 네번째 칸 -->
			<th>조회수</th>
		</tr>
		
		<c:forEach items="${list}" var="boardVO">
			<tr>
				<td>${boardVO.board_number}</td>
				<td><a href="/board/read${pageMaker.makeQuery(pageMaker.cri.page)}&board_number=${boardVO.board_number}">${boardVO.title }</a></td>
				<td>${boardVO.name}</td>
				<td><fmt:formatDate pattern="YYYY-MM-dd" value="${boardVO.create_date}"/></td>
				<td>${boardVO.view_count}</td>
			</tr>
		</c:forEach>
	</table>
	
	<!-- 페이지 번호 -->	
	<div>
		<ul>	
			<!-- 맨처음 버튼 -->
			<li>
				<a href="listPage${pageMaker.makeQuery(pageMaker.firstPage)}">맨처음</a>
			</li>
			
			
			<!-- 이전 버튼 -->
			<li>
				<a href="listPage${pageMaker.makeQuery(pageMaker.startPage-1)}">이전</a>
			</li>
			
			<!-- 페이지 번호 (시작 페이지 번호부터 끝 페이지 번호까지) -->
			<c:forEach begin="${pageMaker.startPage}" end="${pageMaker.endPage}" var="idx">
			    <li>
				    <a href="listPage${pageMaker.makeQuery(idx)}">
				    	<!-- 시각 장애인을 위한 추가 -->
				      	<span>${idx}</span>
				    </a>
			    </li>
			</c:forEach>
			
			<!-- next 버튼 -->
			<li>
			    <a href="listPage${pageMaker.makeQuery(pageMaker.endPage + 1)}">다음</a>
			</li>
			
			<li>
				<a href="listPage${pageMaker.makeQuery(pageMaker.finalPage)}">맨끝</a>
			</li>
			
		</ul>
	</div>
	
</body>
</html>

 

이제 listPage.jsp를  출력해보겠습니다.

 

 

정상적으로 출력이 되지만 보기가 불편합니다.

편의를 위해 부트스트랩을 이용할건데요 다음과 같이 추가해주시면 됩니다.

 

<%@ 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">
<title>Insert title here</title>

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">

	<style type="text/css">
			li {list-style: none; float: left; padding: 6px;}
			 a:link { color: black; text-decoration: none;}
			 a:visited { color: black; text-decoration: none;}
			 a:hover { color: blue; text-decoration: underline;}
			 
			 th { text-align: center; }
			 table { text-align: center; }
			 h1 { padding: 40px}
			 
	</style>

	<script>
		var register = "${register}";
		if(register === "registerOK") {
			alert("등록 되었습니다.");
		}
		
		var result = "${result}";
		if(result === "deleteOK") {
			alert("삭제 되었습니다.");
		}
	</script>
	
		

</head>
<body>

	<h1 align="center"><a href="/">게시판</a></h1><hr />
		
	<div class="container">
		<a href="/board/register"><button class="btn btn-primary">새글 작성</button></a>
	</div>
	
	<div class="container">
		<table class="table table-bordered">
		
			<tr> <!-- 한줄 -->
				<th>번호</th> <!-- 첫번째 칸 -->
				<th>제목</th> <!-- 두번째 칸 -->
				<th>작성자</th> <!-- 세번째 칸 -->
				<th>작성일자</th> <!-- 네번째 칸 -->
				<th>조회수</th>
			</tr>
			
			<c:forEach items="${list}" var="boardVO">
				<tr>
					<td>${boardVO.board_number}</td>
					<td><a href="/board/read${pageMaker.makeQuery(pageMaker.cri.page)}&board_number=${boardVO.board_number}">${boardVO.title }</a></td>
					<td>${boardVO.name}</td>
					<td><fmt:formatDate pattern="YYYY-MM-dd" value="${boardVO.create_date}"/></td>
					<td>${boardVO.view_count}</td>
				</tr>
			</c:forEach>
		</table>
	</div>
	
	<!-- 페이지 번호 -->	
	<div class="text-center">
		<ul class="pagination">	
			<!-- 맨처음 버튼 -->
			<li>
				<a href="listPage${pageMaker.makeQuery(pageMaker.firstPage)}">맨처음</a>
			</li>
			
			
			<!-- 이전 버튼 -->
			<c:if test="${pageMaker.prev}">
				<li>
					<a href="listPage${pageMaker.makeQuery(pageMaker.startPage-1)}">이전</a>
				</li>
			</c:if>
			
			
			<!-- 페이지 번호 (시작 페이지 번호부터 끝 페이지 번호까지) -->
			<c:forEach begin="${pageMaker.startPage}" end="${pageMaker.endPage}" var ="idx">
					<li <c:out value="${pageMaker.cri.page == idx ? 'class=active' : '' }"/>>
						<a href="/board/listPage${pageMaker.makeQuery(idx)}">
					
							<span>${idx}</span>
						</a>
					</li>
				</c:forEach>
			
			<!-- next 버튼 -->
			<c:if test="${pageMaker.next}">
				<li>
			    	<a href="listPage${pageMaker.makeQuery(pageMaker.endPage + 1)}">다음</a>
				</li>
			</c:if>
			
			
			<li>
				<a href="listPage${pageMaker.makeQuery(pageMaker.finalPage)}">맨끝</a>
			</li>
			
		</ul>
	</div>
	
</body>
</html>

 

부트스트랩을 추가하고 다시 listPage를 조회하면

 

 

 

다음과 같이 깔끔해졌습니다.

저렇게 코드로만 올리면 보기 힘들기 때문에 수정한 점에 대해 설명하겠습니다.

 

1. 부트스트랩을 사용할 수 있도록 코드 추가

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">

 

2. 게시판 목록 테이블 수정

<div class="container">
		<table class="table table-bordered">
		
			<tr> <!-- 한줄 -->
				<th>번호</th> <!-- 첫번째 칸 -->
				<th>제목</th> <!-- 두번째 칸 -->
				<th>작성자</th> <!-- 세번째 칸 -->
				<th>작성일자</th> <!-- 네번째 칸 -->
				<th>조회수</th>
			</tr>
			
			<c:forEach items="${list}" var="boardVO">
				<tr>
					<td>${boardVO.board_number}</td>
					<td><a href="/board/read${pageMaker.makeQuery(pageMaker.cri.page)}&board_number=${boardVO.board_number}">${boardVO.title }</a></td>
					<td>${boardVO.name}</td>
					<td><fmt:formatDate pattern="YYYY-MM-dd" value="${boardVO.create_date}"/></td>
					<td>${boardVO.view_count}</td>
				</tr>
			</c:forEach>
		</table>
	</div>

 

- div 태그를 이용하여 class를 container로 설정 해주었는데 이유는 사용자가 보기 편하도록 알맞은 크기로 설정해줍니다.

- table 태그의 table table-bordered는 테이블 형식에 맞추어 꾸며주었습니다.

 

3. 페이지 번호

 

<!-- 페이지 번호 -->	
	<div class="text-center">
		<ul class="pagination">	
			<!-- 맨처음 버튼 -->
			<li>
				<a href="listPage${pageMaker.makeQuery(pageMaker.firstPage)}">맨처음</a>
			</li>
			
			
			<!-- 이전 버튼 -->
			<c:if test="${pageMaker.prev}">
				<li>
					<a href="listPage${pageMaker.makeQuery(pageMaker.startPage-1)}">이전</a>
				</li>
			</c:if>
			
			
			<!-- 페이지 번호 (시작 페이지 번호부터 끝 페이지 번호까지) -->
			<c:forEach begin="${pageMaker.startPage}" end="${pageMaker.endPage}" var ="idx">
					<li <c:out value="${pageMaker.cri.page == idx ? 'class=active' : '' }"/>>
						<a href="/board/listPage${pageMaker.makeQuery(idx)}">
					
							<span>${idx}</span>
						</a>
					</li>
				</c:forEach>
			
			<!-- next 버튼 -->
			<c:if test="${pageMaker.next}">
				<li>
			    	<a href="listPage${pageMaker.makeQuery(pageMaker.endPage + 1)}">다음</a>
				</li>
			</c:if>
			
			
			<li>
				<a href="listPage${pageMaker.makeQuery(pageMaker.finalPage)}">맨끝</a>
			</li>
			
		</ul>
	</div>

 

<div class="text-center">

- div태그로 페이지 번호를 출력하는 부분을 감싸 가운데 정렬.


<ul class="pagination">

- 페이지 번호를 보기 편하도록 꾸밈.

 

<!-- 페이지 번호 부분 -->

<li <c:out value="${pageMaker.cri.page == idx ? 'class=active' : '' }"/>>

 

- JSTL의 c:out 태그로 삼항연산자를 사용해 page 번호와 idx(page 번호)가 같으면 부트스트랩의 'class=active'로 활성화 기능

 

<!-- 이전 버튼 -->

<c:if test="${pageMaker.prev}">
	<li>
		<a href="listPage${pageMaker.makeQuery(pageMaker.startPage-1)}">이전</a>
	</li>
</c:if>

<!-- 다음 버튼 -->

<c:if test="${pageMaker.next}">
	<li>
		<a href="listPage${pageMaker.makeQuery(pageMaker.endPage + 1)}">다음</a>
	</li>
</c:if>

 

마찬가지로 JSTL의 if문을 이용하는데요.

pageMaker에서 다음과 같이 다음버튼과 이전 버튼을 작성한 것을 기억하시나요?

this.prev = startPage == 1? false : true;

this.next = (endPage * perPageNum) <= totalDataCount ? true : false;

 

다음과 같이 페이지 번호가 1이면 이전 페이지가 없기 때문에 false로 보이지 않도록 처리하고,

(끝페이지) * (보여지는 페이지 수) 보다 전체 데이터가 더 많으면 true 처리를 하여 다음버튼으로 갈 수 있도록 처리했습니다.

 

페이지 번호

 

예를 들어 시작페이지가 1이고 끝페이지가 10이라고 가정한다면

for문을 이용해 1, 2 ,3 .... 이렇게 출력이 되도록 하고

uriComponents를 이용하여 url을 생성해주면

해당 페이지(2)를 클릭했을 때 

criteria의 getDataStart메서드가 실행되어

public int getDataStart() {
	return (this.page - 1) * perPageNum;
}

mapper의 limit 부분이 실행되어 21번 데이터부터 10개가 출력이 됩니다.

'JAVA > blog' 카테고리의 다른 글

검색 (1)  (0) 2020.07.23
페이징 처리(5)  (0) 2020.07.19
페이지 처리(3)  (0) 2020.07.16
페이징 처리(2)  (0) 2020.07.11
페이징 처리(1)  (0) 2020.07.11

+ Recent posts