페이징 플러그인을 적용해 간단히... 또 검색 기능까지 활용할 수 있지만..
어디를 면접가도
페이징 할 수 있어요?
네!
인터넷으로 검색 안 하고요?
그건... 좀.. 오래 걸릴 거 같아요..
라는 뻔한 레퍼토리가 나오기 십상이다.
이 글을 통해 다시 한번 기억을 되짚어 보면서 반성해보려 한다.
이 글은 유튜브 동영상에서 조금 모자랐던 코드를 수정해서 만들었다.
-결과물-
생성할 페이징 기능(목표):
1. 보여줄 글 개수 정하는 셀렉트 박스 -> 10개, 20개, 30개
2. 페이징(페이지는 5개씩)
3. 이전, 다음 버튼 생성
참고하면서 만들면 편할거 같다.
페이징을 하기위해 필요한 파일작성을 차근차근 프로젝트 상단부터 아래로 만들어 보자.
MainContoller.java
@Controller
public class MainController {
@Resource(name="ServiceMember")
private memberImpl aa;
@RequestMapping(value="/")
public String main(Model model) {
return "index";
}
@RequestMapping(value="tables")
public String tables(Model model,@RequestParam(defaultValue = "1") String pagenum,@RequestParam(defaultValue = "10") String contentnum) throws Exception{
aa.execute(model, pagenum, contentnum);
return "tables";
}
}
@RequestParam(defaultValue ="값")은
맵핑으로 tables로 들어왔을 때 변수 pagenum과 contentnum의 값을 같이 보내주지 않은 경우 default값으로 원하는 값을 설정해줄 수 있다.
MainMapper.java
@Repository("daoDB")
public interface MainMapper {
public List<MemberDTO> testlist(int pagenum, int contentnum);
public int testcount();
}
BoardPager.java
public class BoardPager {
private int totalcount; // 페이징에 적용할 전체 데이터 갯수
private int pagenum; // 현재 페이지 번호
private int contentnum; // 한페이지에 몇개 표시할지
private int startPage=1; // 현재 페이지 블록의 시작 페이지
private int endPage=5; // 현재 페이지 블럭의 마지막 페이지
private boolean prev; // 이전 페이지로 가는 화살표
private boolean next; // 다음 페이지로 가는 화살표
private int currentblock; // 현재 페이지 블록
private int lastblock; // 마지막 페이지 블록
public void prevnext(int pagenum){
//이전 , 다음 페이지 블록
if(calcpage(totalcount,contentnum)<6){
setPrev(false);
setNext(false);
}else if(pagenum>0 && pagenum<6){
setPrev(false);
setNext(true);
}else if(getLastblock() == getCurrentblock()){
setPrev(true);
setNext(false);
}else{
setPrev(true);
setNext(true);
}
}
public int calcpage(int totalcount, int contentnum){ // 전체페이지 수를 계산하는 함수
//125 / 10 => 12.5
//13페이지
int totalpage = totalcount / contentnum;
if(totalcount%contentnum>0){
totalpage++;
}
return totalpage;
}
public int getTotalcount() {
return totalcount;
}
public void setTotalcount(int totalcount) {
this.totalcount = totalcount;
}
public int getPagenum() {
return pagenum;
}
public void setPagenum(int pagenum) {
this.pagenum = pagenum;
}
public int getContentnum() {
return contentnum;
}
public void setContentnum(int contentnum) {
this.contentnum = contentnum;
}
public int getStartPage() {
return startPage;
}
public void setStartPage(int currentblock) {
this.startPage = (currentblock*5)-4;
/*
* 1 // 1 2 3 4 5
* 2 // 6 7 8 9 10
* 3 // 11 12 13
* */
}
public int getEndPage() {
return endPage;
}
public void setEndPage(int getlastblock, int getcurrentblock) {
// 마지막 페이지 블록을 구하는 곳
if(getlastblock == getcurrentblock){
this.endPage = calcpage(getTotalcount(),getContentnum()); // 전체페이지 개수가 오는곳
}else{
this.endPage = getStartPage()+4;
}
}
public boolean isPrev() {
return prev;
}
public void setPrev(boolean prev) {
this.prev = prev;
}
public boolean isNext() {
return next;
}
public void setNext(boolean next) {
this.next = next;
}
public int getCurrentblock() {
return currentblock;
}
public void setCurrentblock(int pagenum) {
//현재페이지 블록 구하는 곳 페이지 번호를 통해서 구한다.
//페이지 번호 / 페이지 그룹안의 페이지 개수
// 1p => 1 / 5 => 0.2 + 1 = 현재 페이지블록 1
// 3p => 3 / 5 => 0.xx + 1 = 현재 페이지 블록 1
this.currentblock = pagenum/5;
if(pagenum%5>0){
this.currentblock++;
}
}
public int getLastblock() {
return lastblock;
}
public void setLastblock(int lastblock) {
//10 , 5 = > 10 * 5 => 50
// 12 5 / 50
// 3
this.lastblock = totalcount / (5*this.contentnum);
if(totalcount %(5*this.contentnum)>0){
this.lastblock++;
}
}
}
MemberDTO.java
public class MemberDTO {
private String id;
private String password;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
MemberImpl.java
@Service("ServiceMember")
public class memberImpl implements ServiceMember{
@Resource(name="daoDB")
private MainMapper mm;
@Override
public int execute(Model model,String pagenum, String contentnum) {
BoardPager pagemaker = new BoardPager();
int cpagenum = Integer.parseInt(pagenum);
int ccontentnum = Integer.parseInt(contentnum);
List<MemberDTO> testList = null;
pagemaker.setTotalcount(mm.testcount()); // mapper 전체 게시글 개수를 지정한다
pagemaker.setPagenum(cpagenum-1); // 현재 페이지를 페이지 객체에 지정한다 -1 을 해야 쿼리에서 사용할수 있다
pagemaker.setContentnum(ccontentnum); // 한 페이지에 몇개씩 게시글을 보여줄지 지정한다.
pagemaker.setCurrentblock(cpagenum); // 현재 페이지 블록이 몇번인지 현재 페이지 번호를 통해서 지정한다.
pagemaker.setLastblock(pagemaker.getTotalcount()); // 마지막 블록 번호를 전체 게시글 수를 통해서 정한다.
pagemaker.prevnext(cpagenum);//현재 페이지 번호로 화살표를 나타낼지 정한다.
pagemaker.setStartPage(pagemaker.getCurrentblock()); // 시작 페이지를 페이지 블록번호로 정한다.
pagemaker.setEndPage(pagemaker.getLastblock(),pagemaker.getCurrentblock());
//마지막 페이지를 마지막 페이지 블록과 현재 페이지 블록 번호로 정한다.
if(ccontentnum == 10){//선택 게시글 수
testList = mm.testlist(pagemaker.getPagenum()*10,pagemaker.getContentnum());
}else if(ccontentnum == 20){
testList = mm.testlist(pagemaker.getPagenum()*20,pagemaker.getContentnum());
}else if(ccontentnum ==30){
testList = mm.testlist(pagemaker.getPagenum()*30,pagemaker.getContentnum());
}
model.addAttribute("test",testList);
model.addAttribute("page",pagemaker);
return 0;
}
}
ServiceMember.java
public interface ServiceMember {
public int execute(Model model,String pagenum, String contentnum);
}
MainMapper.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.demo.DAO.MainMapper">
<select id="testlist" resultType="com.example.demo.DTO.MemberDTO">
select * from test order by id limit #{pagenum}, #{contentnum}
</select>
<select id="testcount" resultType="int">
select count(*) from test
</select>
</mapper>
Table쪽은 id,password 칼럼으로 구성했고 id는 시퀀스를 생성해줬다.
(페이징처리가 잘되었는지 테스트해보기 위해 데이터가 많이 필요하기 때문에 해줬다.)
데이터 생성을 위해 해준 쿼리문
insert into testdemo.test(id,password) values(1,"0000");
//우선 데이터를 하나 생성해준다.
insert into testdemo.test(password) (select password from testdemo.test);
//values부분에 테이블 전체값을 넣어줌으로서 쿼리문을 한 번 실행 해줄 때 마다 테이블의 데이터가 곱하기2씩 늘어나게 된다.
1...2...4...8...16...32 ...
tables.jsp
<script type="text/javascript">
/*한페이지당 게시물 */
function page(idx){
var pagenum = idx;
var contentnum = $("#contentnum option:selected").val();
if(contentnum == 10){
location.href="${pageContext.request.contextPath}/tables?pagenum="+pagenum+"&contentnum="+contentnum
}else if(contentnum == 20){
location.href="${pageContext.request.contextPath}/tables?pagenum="+pagenum+"&contentnum="+contentnum
}else if(contentnum == 30){
location.href="${pageContext.request.contextPath}/tables?pagenum="+pagenum+"&contentnum="+contentnum
}
}
</script>
<--! 한번에 보여줄 개수 정하기 -->
<select name="contentnum" id="contentnum" onchange="page(1)">
<option value="10" <c:if test="${page.getContentnum() == 10 }">selected="selected"</c:if> >10 개</option>
<option value="20" <c:if test="${page.getContentnum() == 20 }">selected="selected"</c:if> >20 개</option>
<option value="30" <c:if test="${page.getContentnum() == 30 }">selected="selected"</c:if> >30 개</option>
</select>
<--! 페이징 데이터-->
<table class="table table-bordered" width="100%" cellspacing="0">
<thead>
<tr>
<th>id</th>
<th>password</th>
</tr>
</thead>
<tbody>
<c:forEach items="${test}" var="test">
<tr>
<td>${test.id}</td>
<td>${test.password}</td>
</tr>
</c:forEach>
</tbody>
<tfoot>
<div class="row">
<tr>
<td colspan="14">
<--! 페이징 -->
<c:if test="${page.prev}">
<a href="javascript:page(${page.getStartPage()-1});">«</a>
</c:if>
<c:forEach begin="${page.getStartPage()}" end="${page.getEndPage()}" var="idx">
<a href="javascript:page(${idx});">${idx}</a>
</c:forEach>
<c:if test="${page.next}">
<a href="javascript:page(${page.getEndPage()+1});">»</a>
</c:if>
</td>
</tr>
</div>
</tfoot>
</table>
본인 프로젝트에 적당히 넣어주도록 하자.
필자는 sb-admin2 템플릿을 사용했기 때문에 태그에 붙어있는 class나 colspan등은 신경 쓰지 않아도 된다.
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
jsp에서 c태그를 사용하기 위해서는 위와 같은 설정이 필요하다.(jsp파일 맨 상단에 넣어주도록 하자.)
tip.
<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" language="java"%>
jsp에서 한글을 썼는데 안 보인다? 외계 문자로 나온다?면 붙여볼 것
이렇게 모든 코드를 붙였다면 실행해보자.
- 결과 -
잘 적용된 것을 볼 수 있다.