스프링 페이징 처리 - seupeuling peijing cheoli

Spring - 게시판 만들기 연습(페이징 처리)

  • 2017. 2. 20. 00:26
  • 스프링 프레임워크/스프링 MVC 예전 포스팅

Spring - 게시판 만들기 연습(페이징 처리)

1. 실행화면

01) 게시글 목록의 페이지, 다음, 이전, 처음, 끝 버튼 생성, 현재페이지 하이퍼링크 하이퍼링크제거

02) 게시글 검색 후 페이지 이동시(끝페이지 이동, 상세화면으로 이동) 검색 내용이 손실되지 않게 처리

2. 소스코드

01) Controller(흐름제어)

BoardController

@RequestMapping("list.do")

// @RequestParam(defaultValue="") ==> 기본값 할당 : 현재페이지를 1로 초기화

public ModelAndView list(@RequestParam(defaultValue="title"String searchOption,

                        @RequestParam(defaultValue=""String keyword,

                        @RequestParam(defaultValue="1"int curPage) throws Exception{

    int count = boardService.countArticle(searchOption, keyword);

    BoardPager boardPager = new BoardPager(count, curPage);

    int start = boardPager.getPageBegin();

    int end = boardPager.getPageEnd();

    List<BoardVO> list = boardService.listAll(start, end, searchOption, keyword);

    Map<String, Object> map = new HashMap<String, Object>();

    map.put("list", list); // list

    map.put("count", count); // 레코드의 갯수

    map.put("searchOption", searchOption); // 검색옵션

    map.put("keyword", keyword); // 검색키워드

    map.put("boardPager", boardPager);

    ModelAndView mav = new ModelAndView();

    mav.addObject("map", map); // 맵에 저장된 데이터를 mav에 저장

    mav.setViewName("board/list"); // 뷰를 list.jsp로 설정

    return mav; // list.jsp로 List가 전달된다.

cs

02) Service(비지니스로직, DB연동 이외의 작업처리)

BoardPager(페이지 나누기 관련 작업 클래스)

package com.example.spring02.service.board;

public class BoardPager {

    public static final int PAGE_SCALE = 10;

    public static final int BLOCK_SCALE = 10;

    private int curPage; // 현재 페이수

    private int prevPage; // 이전 페이지

    private int nextPage; // 다음 페이지

    private int totPage; // 전체 페이지 갯수

    private int totBlock; // 전체 페이지 블록 갯수

    private int curBlock; // 현재 페이지 블록 

    private int prevBlock; // 이전 페이지 블록

    private int nextBlock; // 다음 페이지 블록

    // WHERE rn BETWEEN #{start} AND #{end}

    private int pageBegin; // #{start}

    private int pageEnd; // #{end}

    // [이전] blockBegin -> 41 42 43 44 45 46 47 48 49 50 [다음]

    private int blockBegin; // 현재 페이지 블록의 시작번호

    // [이전] 41 42 43 44 45 46 47 48 49 50 <- blockEnd [다음]

    private int blockEnd; // 현재 페이지 블록의 끝번호

    // BoardPager(레코드 갯수, 현재 페이지 번호)

    public BoardPager(int count, int curPage){

        curBlock = 1// 현재 페이지 블록 번호

        this.curPage = curPage; // 현재 페이지 설정

        setTotPage(count); // 전체 페이지 갯수 계산

        setTotBlock(); // 전체 페이지 블록 갯수 계산

        setBlockRange(); // 페이지 블록의 시작, 끝 번호 계산

    public void setBlockRange(){

        // *현재 페이지가 몇번째 페이지 블록에 속하는지 계산

        curBlock = (int)Math.ceil((curPage-1/ BLOCK_SCALE)+1;

        // *현재 페이지 블록의 시작, 끝 번호 계산

        blockBegin = (curBlock-1)*BLOCK_SCALE+1;

        blockEnd = blockBegin+BLOCK_SCALE-1;

        // *마지막 블록이 범위를 초과하지 않도록 계산

        if(blockEnd > totPage) blockEnd = totPage;

        prevPage = (curPage == 1)? 1:(curBlock-1)*BLOCK_SCALE;

        nextPage = curBlock > totBlock ? (curBlock*BLOCK_SCALE) : (curBlock*BLOCK_SCALE)+1;

        // 마지막 페이지가 범위를 초과하지 않도록 처리

        if(nextPage >= totPage) nextPage = totPage;

    public void setPageRange(){

    // WHERE rn BETWEEN #{start} AND #{end}

        // 시작번호 = (현재페이지-1)*페이지당 게시물수 +1

        pageBegin = (curPage-1)*PAGE_SCALE+1;

        // 끝번호 = 시작번호+페이지당 게시물수 -1

        pageEnd = pageBegin+PAGE_SCALE-1;

    public int getCurPage() {

    public void setCurPage(int curPage) {

    public int getPrevPage() {

    public void setPrevPage(int prevPage) {

        this.prevPage = prevPage;

    public int getNextPage() {

    public void setNextPage(int nextPage) {

        this.nextPage = nextPage;

    public int getTotPage() {

    public void setTotPage(int count) {

        totPage = (int) Math.ceil(count*1.0 / PAGE_SCALE);

    public int getTotBlock() {

    // 페이지 블록의 갯수 계산(총 100페이지라면 10개의 블록)

    public void setTotBlock() {

        totBlock = (int)Math.ceil(totPage / BLOCK_SCALE);

    public int getCurBlock() {

    public void setCurBlock(int curBlock) {

        this.curBlock = curBlock;

    public int getPrevBlock() {

    public void setPrevBlock(int prevBlock) {

        this.prevBlock = prevBlock;

    public int getNextBlock() {

    public void setNextBlock(int nextBlock) {

        this.nextBlock = nextBlock;

    public int getPageBegin() {

    public void setPageBegin(int pageBegin) {

        this.pageBegin = pageBegin;

    public int getPageEnd() {

    public void setPageEnd(int pageEnd) {

    public int getBlockBegin() {

    public void setBlockBegin(int blockBegin) {

        this.blockBegin = blockBegin;

    public int getBlockEnd() {

    public void setBlockEnd(int blockEnd) {

        this.blockEnd = blockEnd;

cs

BoardService(인터페이스) - 매개변수 int start, int end 추가

public List<BoardVO> listAll(int start, int end, String searchOption, String keyword) throws Exception;

cs

BoardServiceImpl(인터페이스 구현 클래스)

public List<BoardVO> listAll(int start, int end, String searchOption, String keyword) throws Exception {

    return boardDao.listAll(start, end, searchOption, keyword);

cs

03) Model(비지니스로직, DB연동 작업처리)

BoardDAO(인터페이스)

public List<BoardVO> listAll(int start, int end, String searchOption, String keyword) throws Exception;

cs

BoardDAOImpl(인터페이스 구현 클래스)

public List<BoardVO> listAll(int start, int end, String searchOption, String keyword) throws Exception {

    Map<String, Object> map = new HashMap<String, Object>();

    map.put("searchOption", searchOption);

    map.put("keyword", keyword);

    // BETWEEN #{start}, #{end}에 입력될 값을 맵에 

    return SqlSession.selectList("board.listAll", map);

cs

boardMapper.xml

<!-- 게시글 전체 목록 조회 및 검색조회까지 -->

<select id="listAll" resultType="com.example.spring02.model.board.dto.BoardVO">

    <!-- 목록 조회 및 페이징 전체 쿼리 -->

    <include refid="pagingHeader"></include>

        SELECT rownum, bno, title, content, b.regdate, viewcnt, user_name as userName

        FROM tbl_board b, tbl_member m

        <include refid="search"></include>

        ORDER BY bno DESC, b.regdate DESC 

    <include refid="pagingFooter"></include>    

        <when test="searchOption == 'all'">

            WHERE b.writer = m.user_id

            (user_name like '%'||#{keyword}||'%'

            OR content like '%'||#{keyword}||'%'

            OR title like '%'||#{keyword}||'%')

            WHERE b.writer = m.user_id 

            AND ${searchOption} like '%'||#{keyword}||'%'

        SELECT ROWNUM AS rn, A.* FROM (

    ) WHERE rn BETWEEN #{start} AND #{end}

cs

04) View(화면)

list.jsp(게시글 목록)

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<%@ include file="../include/header.jsp" %>

    $(document).ready(function(){

        $("#btnWrite").click(function(){

            location.href = "${path}/board/write.do";

    // **원하는 페이지로 이동시 검색조건, 키워드 값을 유지하기 위해 

        location.href="${path}/board/list.do?curPage="+page+"&searchOption-${map.searchOption}"+"&keyword=${map.keyword}";

<%@ include file="../include/menu.jsp" %>

    <form name="form1" method="post" action="${path}/board/list.do">

        <select name="searchOption">

            <!-- 검색조건을 검색처리후 결과화면에 보여주기위해  c:out 출력태그 사용, 삼항연산자 -->

            <option value="all" <c:out value="${map.searchOption == 'all'?'selected':''}"/> >제목+이름+제목</option>

            <option value="user_name" <c:out value="${map.searchOption == 'user_name'?'selected':''}"/> >이름</option>

            <option value="content" <c:out value="${map.searchOption == 'content'?'selected':''}"/> >내용</option>

            <option value="title" <c:out value="${map.searchOption == 'title'?'selected':''}"/> >제목</option>

        <input name="keyword" value="${map.keyword}">

        <input type="submit" value="조회">

    <!-- 로그인한 사용자만 글쓰기 버튼을 활성화 -->

    <c:if test="${sessionScope.userId != null}">

        <button type="button" id="btnWrite">글쓰기</button>

    ${map.count}개의 게시물이 있습니다.

    <table border="1" width="600px">

        <c:forEach var="row" items="${map.list}">

            <!-- ** 게시글 상세보기 페이지로 이동시 게시글 목록페이지에 있는 검색조건, 키워드, 현재페이지 값을 유지하기 위해 -->

            <td><a href="${path}/board/view.do?bno=${row.bno}&curPage=${map.boardPager.curPage}&searchOption=${map.searchOption}&keyword=${map.keyword}">${row.title}</a></td>

                <!-- 원하는 날짜형식으로 출력하기 위해 fmt태그 사용 -->

                <fmt:formatDate value="${row.regdate}" pattern="yyyy-MM-dd HH:mm:ss"/>

                <!-- **처음페이지로 이동 : 현재 페이지가 1보다 크면  [처음]하이퍼링크를 화면에 출력-->

                <c:if test="${map.boardPager.curBlock > 1}">

                    <a href="javascript:list('1')">[처음]</a>

                <!-- **이전페이지 블록으로 이동 : 현재 페이지 블럭이 1보다 크면 [이전]하이퍼링크를 화면에 출력 -->

                <c:if test="${map.boardPager.curBlock > 1}">

                    <a href="javascript:list('${map.boardPager.prevPage}')">[이전]</a>

                <!-- **하나의 블럭에서 반복문 수행 시작페이지부터 끝페이지까지 -->

                <c:forEach var="num" begin="${map.boardPager.blockBegin}" end="${map.boardPager.blockEnd}">

                    <!-- **현재페이지이면 하이퍼링크 제거 -->

                        <c:when test="${num == map.boardPager.curPage}">

                            <span style="color: red">${num}</span>&nbsp;

                            <a href="javascript:list('${num}')">${num}</a>&nbsp;

                <!-- **다음페이지 블록으로 이동 : 현재 페이지 블럭이 전체 페이지 블럭보다 작거나 같으면 [다음]하이퍼링크를 화면에 출력 -->

                <c:if test="${map.boardPager.curBlock <= map.boardPager.totBlock}">

                    <a href="javascript:list('${map.boardPager.nextPage}')">[다음]</a>

                <!-- **끝페이지로 이동 : 현재 페이지가 전체 페이지보다 작거나 같으면 [끝]하이퍼링크를 화면에 출력 -->

                <c:if test="${map.boardPager.curPage <= map.boardPager.totPage}">

                    <a href="javascript:list('${map.boardPager.totPage}')">[끝]</a>

cs

view.jsp(게시글 상세보기)

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<%@ include file="../include/header.jsp" %>

    $(document).ready(function(){

        // ** 목록 버튼 클릭 이벤트 : 버튼 클릭시 상세보기화면에 있던 페이지, 검색옵션, 키워드 값을 가지로 목록으로 이동

        $("#btnList").click(function(){

            location.href="${path}/board/list.do?curPage=${curPage}&searchOption=${searchOption}&keyword=${keyword}";

        $("#btnDelete").click(function(){

            if(confirm("삭제하시겠습니까?")){

                document.form1.action = "${path}/board/delete.do";

        $("#btnUpdete").click(function(){

            //var title = document.form1.title.value; ==> name속성으로 처리할 경우

            //var content = document.form1.content.value;

            //var writer = document.form1.writer.value;

            var title = $("#title").val();

            var content = $("#content").val();

            //var writer = $("#writer").val();

                document.form1.title.focus();

                document.form1.content.focus();

                document.form1.writer.focus();

            document.form1.action="${path}/board/update.do"

<%@ include file="../include/menu.jsp" %>

<form name="form1" method="post">

    <div>        <!-- 원하는 날짜형식으로 출력하기 위해 fmt태그 사용 -->

        작성일자 : <fmt:formatDate value="${dto.regdate}" pattern="yyyy-MM-dd a HH:mm:ss"/>

                <!-- 날짜 형식 => yyyy 4자리연도, MM 월, dd 일, a 오전/오후, HH 24시간제, hh 12시간제, mm 분, ss 초 -->

        <input name="title" id="title" size="80" value="${dto.title}" placeholder="제목을 입력해주세요">

        <textarea name="content" id="content" rows="4" cols="80" placeholder="내용을 입력해주세요">${dto.content}</textarea>

        <%-- <input name="writer" id="writer" value="${dto.writer}" placeholder="이름을 입력해주세요"> --%>

    <div style="width:650px; text-align: center;">

        <!-- 게시물번호를 hidden으로 처리 -->

        <input type="hidden" name="bno" value="${dto.bno}">

    <!-- 본인이 쓴 게시물만 수정, 삭제가 가능하도록 처리 -->

    <c:if test="${sessionScope.userId == dto.writer}">

        <button type="button" id="btnUpdete">수정</button>

        <button type="button" id="btnDelete">삭제</button>

        <!-- **상세보기 화면에서 게시글 목록화면으로 이동 -->

        <button type="button" id="btnList">목록</button>

cs

Toplist

최신 우편물

태그