페이징 처리

메타플랫폼대표
|2024. 7. 12. 11:30
반응형

원본파일

 

JavaBoardEx/2024_0627_PhotoGallery at main · chaSunil/JavaBoardEx

게시판연습. Contribute to chaSunil/JavaBoardEx development by creating an account on GitHub.

github.com

 

2024_0711_Mybatis_SubQuery [ADD] 페이징처리

 

GitHub - chaSunil/FirstProject: 1차 프로젝트

1차 프로젝트. Contribute to chaSunil/FirstProject development by creating an account on GitHub.

github.com

 

 

 

SQL문 한페이지에 1~5개만 볼 수 있게 하는 SQL문

select * from
(
	select
		rank() over(order by p_idx desc) as no,
		p.*
	from
		(select * from photo) p
)
where no between 1 and 5

 

 

Paging별 조회 Mybatis

	<!-- Paging별 조회 -->
	<select id="photo_list_page" parameterType="Map" resultType="photo">
		select * from
		(
			select
				rank() over(order by p_idx desc) as no,
				p.*
			from
				(select * from photo) p
		)
		where no between #{ start } and #{ end }
	</select>

 

 

Servlet Map안에 start end 정보를 담아주는 Action 작성

/**
 * Servlet implementation class PhotoListAction
 */
@WebServlet("/photo/list.do")
public class PhotoListAction extends HttpServlet {
	private static final long serialVersionUID = 1L;

	/**
	 * @see HttpServlet#service(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void service(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("start",1);
		map.put("end",8);
		
		
		List<PhotoVo> list = PhotoDao.getInstance().selectList();
		
		// request binding
		request.setAttribute("list", list);

		// Dispatcher형식으로 호출
		String forward_page = "photo_list.jsp";
		RequestDispatcher disp = request.getRequestDispatcher(forward_page);
		disp.forward(request, response);

	}

}

 

 

Dao 생성

	public List<PhotoVo> selectList(Map<String, Object> map) {
		
		List<PhotoVo> list = new ArrayList<PhotoVo>();

		// 1. SqlSession 얻어오기
		SqlSession sqlSession = factory.openSession(); // Connection 획득
		
		// 2. 작업수행                namespace
		list = sqlSession.selectList("photo.photo_list_page", map);
		
		// 3. 닫기 : conn.close()과정 포함
		sqlSession.close();

		return list;
	}

 

 

 

 

 

정상적으로 지정해준 갯수만 나온다.

 

 

새로 Class 생성

package util;

public class MyCommon {
	
	public static class Photo{
		
		public static final int BLOCK_LIST = 8; // 한화면에 보여줄 게시물수
	}

}

 

 

Action 수정

package action.photo;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import dao.PhotoDao;
import db.vo.PhotoVo;
import util.MyCommon;

/**
 * Servlet implementation class PhotoListAction
 */
@WebServlet("/photo/list.do")
public class PhotoListAction extends HttpServlet {
	private static final long serialVersionUID = 1L;

	/**
	 * @see HttpServlet#service(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void service(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		
		// /photo/list.do?page=2
		int nowPage = 1;
		try {
			nowPage = Integer.parseInt(request.getParameter("page"));
		} catch (Exception e) {
			// TODO: handle exception
		}
		
		// 게시물의 범위 계산(start/end)
		int start = (nowPage-1) * MyCommon.Photo.BLOCK_LIST + 1;
		int end = start + MyCommon.Photo.BLOCK_LIST - 1;
		
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("start",start);
		map.put("end",end);
		
		
		List<PhotoVo> list = PhotoDao.getInstance().selectList(map);
		
		// request binding
		request.setAttribute("list", list);

		// Dispatcher형식으로 호출
		String forward_page = "photo_list.jsp";
		RequestDispatcher disp = request.getRequestDispatcher(forward_page);
		disp.forward(request, response);

	}

}

 

 

 

Vo에 no추가 Getter Setter 생성

 

		<!-- for(PhotoVo vo: list) -->
		<c:forEach var="vo" items="${ list }">
			<div class="photo" onclick="showPhoto('${ vo.p_idx }')">
				<img src="../images/${ vo.p_filename }">
				<div class="title">${vo.no}.${ vo.p_title }</div>
			</div>
		</c:forEach>
		<!-- Page Menu -->
		<div style="text-align:center; margin-top:20px;">
			<a href="list.do?page=1">1</a>&nbsp&nbsp&nbsp&nbsp
			<a href="list.do?page=2">2</a>&nbsp&nbsp&nbsp&nbsp
			<a href="list.do?page=3">3</a>&nbsp&nbsp&nbsp&nbsp
			<a href="list.do?page=4">4</a>&nbsp&nbsp&nbsp&nbsp
			<a href="list.do?page=5">5</a>&nbsp&nbsp&nbsp&nbsp
		</div>

Paging.java
0.00MB

 

 

Paging.java 추가

package action.util;
/*
        nowPage:현재페이지
        rowTotal:전체데이터갯수
        blockList:한페이지당 게시물수
        blockPage:한화면에 나타낼 페이지 목록수
 */
public class Paging {
	public static String getPaging(String pageURL,int nowPage, int rowTotal,int blockList, int blockPage){
		
		int totalPage/*전체페이지수*/,
            startPage/*시작페이지번호*/,
            endPage;/*마지막페이지번호*/

		boolean  isPrevPage,isNextPage;
		StringBuffer sb; //모든 상황을 판단하여 HTML코드를 저장할 곳
		
		
		isPrevPage=isNextPage=false;
		//입력된 전체 자원을 통해 전체 페이지 수를 구한다..
		totalPage = (int)(rowTotal/blockList);
		if(rowTotal%blockList!=0)totalPage++;
		

		//만약 잘못된 연산과 움직임으로 인하여 현재 페이지 수가 전체 페이지 수를
		//넘을 경우 강제로 현재페이지 값을 전체 페이지 값으로 변경
		if(nowPage > totalPage)nowPage = totalPage;
		

		//시작 페이지와 마지막 페이지를 구함.
		startPage = (int)(((nowPage-1)/blockPage)*blockPage+1);
		endPage = startPage + blockPage - 1; //
		
		//마지막 페이지 수가 전체페이지수보다 크면 마지막페이지 값을 변경
		if(endPage > totalPage)endPage = totalPage;
		
		//마지막페이지가 전체페이지보다 작을 경우 다음 페이징이 적용할 수 있도록
		//boolean형 변수의 값을 설정
		if(endPage < totalPage) isNextPage = true;
		//시작페이지의 값이 1보다 작으면 이전페이징 적용할 수 있도록 값설정
		if(startPage > 1)isPrevPage = true;
		
		//HTML코드를 저장할 StringBuffer생성=>코드생성
		sb = new StringBuffer();
//-----그룹페이지처리 이전 --------------------------------------------------------------------------------------------		
		if(isPrevPage){
			sb.append("<a href ='"+pageURL+"?page=");
			sb.append(nowPage - blockPage);
			sb.append("'>◀</a>");
		}
		else
			sb.append("◀");
		
//------페이지 목록 출력 -------------------------------------------------------------------------------------------------
		sb.append("|");
		for(int i=startPage; i<= endPage ;i++){
			if(i>totalPage)break;
			if(i == nowPage){ //현재 있는 페이지
				sb.append("&nbsp;<b><font color='#91b72f'>");
				sb.append(i);
				sb.append("</font></b>");
			}
			else{//현재 페이지가 아니면
				sb.append("&nbsp;<a href='"+pageURL+"?page=");
				sb.append(i);
				sb.append("'>");
				sb.append(i);
				sb.append("</a>");
			}
		}// end for
		
		sb.append("&nbsp;|");
		
//-----그룹페이지처리 다음 ----------------------------------------------------------------------------------------------
		if(isNextPage){
			sb.append("<a href='"+pageURL+"?page=");
			if(nowPage+blockPage > totalPage)nowPage = totalPage;
			else
				nowPage = nowPage+blockPage;
			sb.append(nowPage);
			sb.append("'>▶</a>");
		}
		else
			sb.append("▶");
//---------------------------------------------------------------------------------------------------------------------	    

		return sb.toString();
	}
}

 

 

 

한 화면에 보여줄 페이지수 상수를 만들어준다.

package util;

public class MyCommon {
	
	public static class Photo{
		
		public static final int BLOCK_LIST = 8; // 한화면에 보여줄 게시물수
		public static final int BLOCK_PAGE = 3; // 한화면에 보여줄 페이지수
	}

}

 

 

-- 전체게시물수 구하기
-- null value : null 값이면 0으로 지정한다
select nvl(count(*),0) from photo

 

 

photo.xml에 추가

	<!-- 전체레코드수 구하기 -->
	<select id="photo_row_total" resultType="int">
		select nvl(count(*),0) from photo
	</select>

 

 

Action에 추가

/**
 * Servlet implementation class PhotoListAction
 */
@WebServlet("/photo/list.do")
public class PhotoListAction extends HttpServlet {
	private static final long serialVersionUID = 1L;

	/**
	 * @see HttpServlet#service(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void service(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		
		// /photo/list.do?page=2
		int nowPage = 1;
		try {
			nowPage = Integer.parseInt(request.getParameter("page"));
		} catch (Exception e) {
			// TODO: handle exception
		}
		
		// 게시물의 범위 계산(start/end)
		int start = (nowPage-1) * MyCommon.Photo.BLOCK_LIST + 1;
		int end = start + MyCommon.Photo.BLOCK_LIST - 1;
		
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("start",start);
		map.put("end",end);
		
		
		List<PhotoVo> list = PhotoDao.getInstance().selectList(map);
		
		// 전체 게시물수
		int rowTotal = PhotoDao.getInstance().selectRowTotal();
		
		// pageMenu 만들기
		String pageMenu = Paging.getPaging("list.do",   // pageURL
											nowPage,    // 현재페이지
											rowTotal,   // 전체페이지
											MyCommon.Photo.BLOCK_LIST, // 한화면에 보여질 게시물 수
											MyCommon.Photo.BLOCK_PAGE); // 한화면에 보여질 페이지 수
		
		// request binding
		request.setAttribute("list", list);
		request.setAttribute("pageMenu", pageMenu);

		// Dispatcher형식으로 호출
		String forward_page = "photo_list.jsp";
		RequestDispatcher disp = request.getRequestDispatcher(forward_page);
		disp.forward(request, response);

	}

}

 

 

Dao 추가

	public int selectRowTotal() {

		int total = 0;
		
		// 1. SqlSession 얻어오기
		SqlSession sqlSession = factory.openSession();

		// 2. 작업수행
		total = sqlSession.selectOne("photo.photo_row_total");

		// 3. 닫기 : conn.close() 과정 포함
		sqlSession.close();

		return total;
	}

 

 

pageMenu 안에 담겨있는 로직

		<!-- Page Menu -->
		<div style="text-align:center; margin-top:20px;">
			${ pageMenu }
			<!-- <a href="list.do?page=1">1</a>&nbsp&nbsp&nbsp&nbsp
			<a href="list.do?page=2">2</a>&nbsp&nbsp&nbsp&nbsp
			<a href="list.do?page=3">3</a>&nbsp&nbsp&nbsp&nbsp
			<a href="list.do?page=4">4</a>&nbsp&nbsp&nbsp&nbsp
			<a href="list.do?page=5">5</a>&nbsp&nbsp&nbsp&nbsp -->
		</div>

 

 

		<!-- Page Menu -->
		<div style="text-align:center; margin-top:20px;">
			${ pageMenu }
			
			
			◀|&nbsp;<b><font color='#91b72f'>1</font></b>&nbsp;
			<a href='list.do?page=2'>2</a>&nbsp;
			<a href='list.do?page=3'>3</a>&nbsp;
			<a href='list.do?page=4'>4</a>&nbsp;|▶
			<!-- <a href="list.do?page=1">1</a>&nbsp&nbsp&nbsp&nbsp
			<a href="list.do?page=2">2</a>&nbsp&nbsp&nbsp&nbsp
			<a href="list.do?page=3">3</a>&nbsp&nbsp&nbsp&nbsp
			<a href="list.do?page=4">4</a>&nbsp&nbsp&nbsp&nbsp
			<a href="list.do?page=5">5</a>&nbsp&nbsp&nbsp&nbsp -->
		</div>

 

 

버튼 이쁘게 꾸며봅시다

package action.util;
/*
        nowPage:현재페이지
        rowTotal:전체데이터갯수
        blockList:한페이지당 게시물수
        blockPage:한화면에 나타낼 페이지 목록수
 */
public class Paging {
	public static String getPaging(String pageURL,int nowPage, int rowTotal,int blockList, int blockPage){
		
		int totalPage/*전체페이지수*/,
            startPage/*시작페이지번호*/,
            endPage;/*마지막페이지번호*/

		boolean  isPrevPage,isNextPage;
		StringBuffer sb; //모든 상황을 판단하여 HTML코드를 저장할 곳
		
		
		isPrevPage=isNextPage=false;
		//입력된 전체 자원을 통해 전체 페이지 수를 구한다..
		totalPage = rowTotal/blockList; // total 게시물 개수 / 한페이지 게시물 개수
		if(rowTotal%blockList!=0)totalPage++;
		

		//만약 잘못된 연산과 움직임으로 인하여 현재 페이지 수가 전체 페이지 수를
		//넘을 경우 강제로 현재페이지 값을 전체 페이지 값으로 변경
		if(nowPage > totalPage)nowPage = totalPage;
		

		//시작 페이지와 마지막 페이지를 구함.
		startPage = ((nowPage-1)/blockPage)*blockPage+1;
		endPage = startPage + blockPage - 1; //
		
		//마지막 페이지 수가 전체페이지수보다 크면 마지막페이지 값을 변경
		if(endPage > totalPage)endPage = totalPage;
		
		//마지막페이지가 전체페이지보다 작을 경우 다음 페이징이 적용할 수 있도록
		//boolean형 변수의 값을 설정
		if(endPage < totalPage) isNextPage = true;
		
		
		//시작페이지의 값이 1보다 작으면 이전페이징 적용할 수 있도록 값설정
		if(startPage > 1)isPrevPage = true;
		
		//HTML코드를 저장할 StringBuffer생성=>코드생성
		sb = new StringBuffer("<ul class='pagination'>");
//-----그룹페이지처리 이전 --------------------------------------------------------------------------------------------		
		if(isPrevPage){
			
			sb.append(String.format("<li><a href='list.do?page=%d'>🐈</a></li>", startPage-1));
			/*
			 * sb.append("<a href ='"+pageURL+"?page="); // sb.append(nowPage - blockPage);
			 * sb.append(startPage - 1); // startPage - 1은 이전 page의 마지막 번호로 가진다.
			 * sb.append("'>🐈</a>");
			 */
		}
		else
			sb.append("<li><a href='#'>🐈</a></li>");
		
//------페이지 목록 출력 -------------------------------------------------------------------------------------------------
		// sb.append("|");
		
		for(int i=startPage; i<= endPage ;i++){
			// if(i>totalPage)break;
			if(i == nowPage){ //현재 있는 페이지
				sb.append(String.format(" <li class='active'><a href='#'>%d</a></li>", i));
				/*
				 * sb.append("&nbsp;<b><font color='red'>"); sb.append(i);
				 * sb.append("</font></b>");
				 */
			}
			else{//현재 페이지가 아니면
				sb.append(String.format(" <li><a href='list.do?page=%d'>%d</a></li>", i, i));
				/*
				 * sb.append("&nbsp;<a href='"+pageURL+"?page="); sb.append(i); sb.append("'>");
				 * sb.append(i); sb.append("</a>");
				 */
			}
		}// end for
		
		// sb.append("&nbsp;|");
		
//-----그룹페이지처리 다음 ----------------------------------------------------------------------------------------------
		if(isNextPage){
			sb.append(String.format("<li><a href='list.do?page=%d'>🐑</a></li>", endPage+1));
			/*
			 * sb.append("<a href='"+pageURL+"?page="); sb.append(endPage + 1);
			 * sb.append(nowPage); sb.append("'>🐑</a>");
			 */
		}
		else
			sb.append("<li><a href='#'>🐑</a></li>");
			/* sb.append("🐑"); */
//---------------------------------------------------------------------------------------------------------------------	    

		sb.append("</ul>");
		
		return sb.toString();
	}
}

 

반응형

'데이터베이스↗' 카테고리의 다른 글

MySQL 설치 가이드 / 사용하기  (0) 2024.08.14
게시판 페이징 처리  (1) 2024.07.12
Mybatis Double Table deptMap  (0) 2024.07.11
Mybatis 검색기능 Search  (0) 2024.07.11
Mybatis library 설정과 사용  (0) 2024.07.10