게시판 만들기 (페이지 나누기)

Back-End/Spring 2019. 7. 3. 11:02
728x90
반응형


 - 페이지 나누기 구현 -



 - 페이지당 게시물수 : 10개


 - 전체 게시물수 : 991개


 - 몇 페이지? : 100


 991 / 10 => 99.1 올림 => 100


(99.1에서 올림을 한 이유는 한 페이지에 글이 1개만 들어갈 수도 있기 때문.. (맨 오래전에 쓴 맨 첫글같은 경우))



 - 페이지의 시작번호, 끝번호 계산


 where rn between 1 and 10


 1페이지 => 1 ~ 10

 2페이지 => 11 ~ 20

 .....

 11페이지 => 101 ~ 110

 57페이지 => 561 ~ 570

 99페이지 => 981 ~ 990

 100페이지 => 991 ~ 1000


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


1페이지 => (1-1) * 10 + 1 => 1

2페이지 => (2-1) * 10 + 1 => 11

7페이지 => (7-1) * 10 + 1 => 61


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


1페이지 => 1 + 10 - 1 => 10

2페이지 => 11 + 10 -1 => 20


 * 전체 페이지 블록수 = 전체 페이지 갯수 / 10

(페이지가 한꺼번에 다 나오면 알아보기가 힘들기때문에 10페이지씩 1블록을 만들어 저장)

91 / 10 => 9.1 => 10개


 

예시 )


1    2    3    4    5    6    7    8    9    10    [다음]

[이전]    11    12    13    14    15    16    17    18    19    20    [다음]

[이전]    21    22


22페이지가 끝일 경우에는 그 다음페이지는 표시되지 않아야 하고, [다음] 버튼도 출력되면 안된다.



현재 페이지가 속한 블록 = (현재 페이지 - 1) / 페이지 블록 단위 + 1


1페이지 => 몇번째 블록? 1

(1-1) / 10 + 1 => 1


9페이지 => 1블록

(9-1) / 10 + 1 => 1


11페이지 => 2블록

(11-1) / 10 + 1 => 2


57페이지

(57-1) / 10 + 1 => 6


* 페이지 블록의 시작번호 = (현재블록 - 1) * 블록단위 + 1


1블록 => (1-1) * 10 + 1 => 1

2블록 => (2-1) * 10 + 1 => 11

6블록 => (6-1) * 10 + 1 => 51


* 페이지 블록의 끝번호 = 블록 시작번호 + 블록단위 - 1


1블록 => 1 + 10 - 1 => 10

2블록 => 11 + 10 - 1 => 20

6블록 => 51 + 10 - 1 => 60




board테이블과 member테이블을 join을 해야 작성자의 이름을 알 수 있다.



board 테이블



member 테이블



(연습) board테이블과 member테이블을 join해서 작성자가 작성한 게시글의 정보를 조회하는 쿼리

1
2
3
4
select bno, title, writer, name, regdate, viewcnt // 글번호, 제목, 작성자, 이름, 날짜, 조회수를 검색
from board b, member m // board 테이블과 member테이블로 부터 (b와 m은 약자로 쓴다는 의미)
where b.writer=m.userid // board 테이블의 작성자id와 member 테이블의 회원id가 같은 것을 검색
order by bno desc; // 글번호의 내림차순으로 검색
cs



boardMapper.xml에서 코드를 수정 (위에서 실행해본 SQL 구문을 listAll에 삽입한다)

1
2
3
4
5
6
7
8
9
10
11
12
<!-- 다른 mapper와 중복되지 않도록 네임스페이스 기재 -->
 
<mapper namespace="board">
 
<select id="listAll"
resultType="com.example.spring02.model.board.dto.BoardDTO">
select bno, title, writer, name, regdate, viewcnt     
from board b, member m                               
where b.writer=m.userid                            
order by bno desc;
 
</select>
cs



list.jsp 중 일부 코드 수정 (게시판에서 작성자 이름이 출력될 수 있도록....)

이렇게 하면 name에 join된 이름이 출력되게 된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
<c:forEach var = "row" items = "${map.list}">
    <tr>
        <td>${row.bno}</td>
        <td>${row.title}</td>
        <td>${row.name}</td//write를 name로 변경
        <td><fmt:formatDate value = "${row.regdate}"
            pattern = "yyyy-MM-dd HH:mm:ss" /></td>
        <td>${row.viewcnt}</td>
    </tr>
</c:forEach>
</table>
</body>
</html>
cs



게시물 1000개를 입력하기 위해 데이터베이스에서 반복문을 만들어서 실행한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
declare
    i number := 1-- declare는 선언문, i의 값을 1로 대입하는것을 선언,
begin
    while i <= 1000 loop
        insert into board (bno,title,content,writer) values
        ((select nvl(max(bno)+1,1)from board),'제목'||i, '내용'||i, 'park');
 
        -- 시퀀스를 만들긴 했지만 번호가 깔끔하게 나오지 않기때문에 서브쿼리를 사용해서 번호를 1씩 증가시킨다.
        -- ||는 숫자와 문자열을 더할때 사용한다 이 쿼리에서는 제목1, 제목2 이런식으로 출력이 되게 된다.
        -- id는 member 테이블에 있는 id만 사용해야 한다. 그렇게 해야 join이 되기 때문에
 
        i := i+1;
        --한 바퀴 돌때마다 i를 1씩 증가시킨다는 의미 (1000바퀴 돌때까지)
    end loop;
end;
/


commit; //게시물 1000개를 집어넣은 후 commit를 실시해서 작업을 완료함.
cs


게시물을 한페이지에 10개씩 볼 수 있게하는 쿼리 (연습)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
-- rownum : 출력순서
-- 아래sql 문에서는 원래 from 문이 먼저 실행되고, 
-- where문이 다음으로 실행되고, 
-- 그 다음 맨위쪽 문장이 실행된다.
-- 마지막에는 order by문이 실행된다.
 
select * 
from (
    select rownum as rn, A.* --rownum을 rn이란 문자로 줄여쓴다. 밑에 from문을 A로 줄여쓴다. 
    from ( --이 from문이 먼저 실행된 다음에 번호를 붙였기 때문에 일련번호가 다시 새로 매겨졌다.
        --이 안쪽의 쿼리가 가장 중요함
        select rownum, bno, title, regdate, viewcnt, name --3번째로 실행
        from board b, member m --1번째로 실행
        where b.writer=m.userid --2번째로 실행
        order by bno desc --4번째로 실행
    ) A
where rn between 1 and 10-- 새로매겨진 일련번호 1~10번 글까지 1페이지
                             -- 11~20번 글까지 2페이지 ..
 
cs



페이지를 나누기 위한 클래스 작성


Pager.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
package com.example.spring02.service.board;
 
public class Pager {
    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;     //다음 블록
    private int pageBegin;     // #{start} 변수에 전달될 값
    private int pageEnd;     // #{end} 변수에 전달될 값
    private int blockBegin; //블록의 시작페이지 번호
    private int blockEnd;     //블록의 끝페이지 번호
    
    //생성자
    // Pager(레코드갯수, 출력할페이지번호)
    public Pager(int count, int curPage) {
        curBlock = 1//현재블록 번호
        this.curPage = curPage; //현재 페이지 번호
        setTotPage(count); //전체 페이지 갯수 계산
        setPageRange(); // #{start}, #{end} 값 계산하는 메소드
        setTotBlock(); // 전체 블록 갯수 계산
        setBlockRange(); //블록의 시작,끝 번호 계산
    } 
    public void setBlockRange() {
        //원하는 페이지가 몇번째 블록에 속하는지 계산
        curBlock=(curPage-1)/BLOCK_SCALE + 1;
        //블록의 시작페이지,끝페이지 번호 계산
        blockBegin=(curBlock-1)*BLOCK_SCALE+1;
        blockEnd=blockBegin+BLOCK_SCALE-1;
        //마지막 블록 번호가 범위를 초과하지 않도록 처리
        if(blockEnd > totPage) {
            blockEnd = totPage;
        }
        //[이전][다음]을 눌렀을 때 이동할 페이지 번호
        prevPage=(curBlock==1) ? 1 : (curBlock-1)*BLOCK_SCALE;
        nextPage=curBlock>totBlock ? (curBlock*BLOCK_SCALE)
                : (curBlock*BLOCK_SCALE)+1;
        //마지막 페이지가 범위를 초과하지 않도록 처리
        if(nextPage >= totPage) {
            nextPage=totPage;
        }
    }
    
    //페이지블록의 총 갯수 계산 (총 100페이지라면 10개의 블록이다)
    public void setTotBlock() {
        totBlock = (int)Math.ceil(totPage*1.0 / BLOCK_SCALE);
    }
    
// where rn between #{start} and #{end}에 입력될 값        
    public void setPageRange() {
// 시작번호=(현재페이지-1)x페이지당 게시물수 + 1
// 끝번호=시작번호 + 페이지당 게시물수 - 1        
        pageBegin = (curPage-1* PAGE_SCALE + 1;
        pageEnd = pageBegin + PAGE_SCALE - 1;
    }
    
    public int getCurPage() {
        return curPage;
    }
    public void setCurPage(int curPage) {
        this.curPage = curPage;
    }
    public int getPrevPage() {
        return prevPage;
    }
    public void setPrevPage(int prevPage) {
        this.prevPage = prevPage;
    }
    public int getNextPage() {
        return nextPage;
    }
    public void setNextPage(int nextPage) {
        this.nextPage = nextPage;
    }
    public int getTotPage() {
        return totPage;
    }
    
    //전체 페이지 갯수 계산
    public void setTotPage(int count) {
        // Math.ceil() 올림        
        totPage = (int)Math.ceil(count*1.0 / PAGE_SCALE);
    }
    public int getTotBlock() {
        return totBlock;
    }
    public void setTotBlock(int totBlock) {
        this.totBlock = totBlock;
    }
    public int getCurBlock() {
        return curBlock;
    }
    public void setCurBlock(int curBlock) {
        this.curBlock = curBlock;
    }
    public int getPrevBlock() {
        return prevBlock;
    }
    public void setPrevBlock(int prevBlock) {
        this.prevBlock = prevBlock;
    }
    public int getNextBlock() {
        return nextBlock;
    }
    public void setNextBlock(int nextBlock) {
        this.nextBlock = nextBlock;
    }
    public int getPageBegin() {
        return pageBegin;
    }
    public void setPageBegin(int pageBegin) {
        this.pageBegin = pageBegin;
    }
    public int getPageEnd() {
        return pageEnd;
    }
    public void setPageEnd(int pageEnd) {
        this.pageEnd = pageEnd;
    }
    public int getBlockBegin() {
        return blockBegin;
    }
    public void setBlockBegin(int blockBegin) {
        this.blockBegin = blockBegin;
    }
    public int getBlockEnd() {
        return blockEnd;
    }
    public void setBlockEnd(int blockEnd) {
        this.blockEnd = blockEnd;
    }    
}
cs



BoardController.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
package com.example.spring02.controller.board;
 
import java.util.HashMap;
import java.util.List;
 
import javax.inject.Inject;
import javax.servlet.http.HttpSession;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
 
import com.example.spring02.model.board.dto.BoardDTO;
import com.example.spring02.service.board.BoardService;
import com.example.spring02.service.board.Pager;
@Controller //controller bean
@RequestMapping("board/*"//공통적인 url pattern
public class BoardController {
    @Inject 
    BoardService boardService;
 
    //첨부파일 목록을 리턴
    //ArrayList를 json 배열로 변환하여 리턴
    @RequestMapping("getAttach/{bno}")
    @ResponseBody // view가 아닌 데이터 자체를 리턴 
    public List<String> getAttach(@PathVariable int bno){
        return boardService.getAttach(bno);
    }
    
    @RequestMapping("delete.do")
    public String delete(int bno) throws Exception {
        boardService.delete(bno); //삭제 처리
        return "redirect:/board/list.do"//목록으로 이동
    }
    
//게시물 내용 수정    
    @RequestMapping("update.do")
    public String update(BoardDTO dto) throws Exception {
        System.out.println("dto:"+dto);
        if(dto != null) {
            boardService.update(dto); //레코드 수정
        }
        // 수정 완료 후 목록으로 이동
        //return "redirect:/board/list.do";
        // 상세 화면으로 되돌아감
        return "redirect:/board/view.do?bno="+dto.getBno();
    }
    
    @RequestMapping("list.do"//세부적인 url pattern
    public ModelAndView list(//RequestParam으로 옵션, 키워드, 페이지의 기본값을 각각 설정해준다.
    @RequestParam(defaultValue="1"int curPage,
    @RequestParam(defaultValue="all"String search_option,
    @RequestParam(defaultValue=""String keyword)
    //defaultValue를 설정하지 않으면 null point 에러가 발생할수 있기 때문에 기본값을 설정해주어야 한다.
                        throws Exception{
        //레코드 갯수 계산
        int count = 1000;
        
        //페이지 관련 설정, 시작번호와 끝번호를 구해서 각각 변수에 저장함
        Pager pager=new Pager(count, curPage); //레코드 번호와 원하는 페이지의 번호를 주게 되면 
        int start=pager.getPageBegin();
        int end=pager.getPageEnd();
        
        //게시물 목록을 출력하기 위해 <BoardDTO>타입에 list변수에 게시물 목록관련 값들을 저장함.
        //넣어야될 값들이 여러개 있으므로 haspmap.put 메소드를 사용해서 값들을 넣어서 list에 저자
        
        List<BoardDTO> list= boardService.listAll(search_option,keyword,start,end); //게시물 목록
        
        ModelAndView mav=new ModelAndView(); //자료를 보낼 페이지를 지정해야하고, 자료를 지정해야 하기 때문에 
                                                //ModelAndView 객체를 생성한다.
 
        HashMap<String,Object> map=new HashMap<>(); //여러개의 값들을 저장해야하기 때문에 hashmap() 객체를 생성
        
        map.put("list", list); //map에 자료 저장
        map.put("count", count);
        map.put("pager", pager); //페이지 네비게이션을 위한 변수
        map.put("search_option", search_option);
        map.put("keyword",keyword); 
        mav.setViewName("board/list"); //포워딩할 뷰의 이름
        mav.addObject("map", map); //ModelAndView에 map을 저장
        return mav; // board/list.jsp로 이동
    }
    
    @RequestMapping("view.do")
    public ModelAndView view(int bno, HttpSession session)
        throws Exception {
        //조회수 증가 처리
        boardService.increaseViewcnt(bno, session); 
        ModelAndView mav=new ModelAndView();
        mav.setViewName("board/view"); //포워딩할 뷰의 이름
        mav.addObject("dto", boardService.read(bno)); //자료 저장
        return mav; //  views/board/view.jsp로 넘어가서 출력됨
    } 
    
    @RequestMapping("write.do")
    public String write() {
        // 글쓰기 폼 페이지로 이동
        return "board/write";
    }
    // write.jsp에서 입력한 내용들이 BoardDTO에 저장됨    
    @RequestMapping("insert.do")
    public String insert(@ModelAttribute BoardDTO dto
            , HttpSession session) //세션은 아이디를 확인하기위해서 필요하므로 세션을 가져온다.
        throws Exception {
        
        // 로그인한 사용자의 아이디
        String writer=(String)session.getAttribute("userid");
        dto.setWriter(writer); //로그인한 아이디를 dto에 저장
 
        //레코드 저장
        boardService.create(dto); //서비스와 dao를 통해서 레코드에 추가가된다.
        
        //게시물 목록으로 이동
        return "redirect:/board/list.do";
    }
}
cs



BoardDAOImpl.java 중 일부 (게시물 목록을 리턴하는 메소드를 수정함)

1
2
3
4
5
6
7
8
9
10
11
12
13
//게시물 목록 리턴
    @Override
    public List<BoardDTO> listAll(
String search_option, String keyword,int start, int end) 
                throws Exception {
        Map<String,Object> map=new HashMap<>();
        map.put("search_option", search_option);
        map.put("keyword""%"+keyword+"%");
        map.put("start", start); //맵에 자료 저장
        map.put("end", end);
// mapper에는 2개 이상의 값을 전달할 수 없음(dto 또는 map 사용)        
        return sqlSession.selectList("board.listAll",map); 
    }
cs



boardMapper.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
<?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와 중복되지 않도록 네임스페이스 기재 -->
<mapper namespace="board">
 
    <select id="listAll"
resultType="com.example.spring02.model.board.dto.BoardDTO">
    <!-- 결과는 boardDTO타입이 된 -->
 
        <include refid="paging_header" />
 
    <!-- ref는 다른테이블을 의미한다. -->
    <!-- 번호, 제목, 작성자, 이름, 날짜, 조회수 , 그리고 댓글의 갯수를 검색 -->
    <!-- board 테이블과 member 테이블로 부터 검색 -->
            select bno,title,writer,name,regdate,viewcnt,show
                  ,(select count(*) from reply where bno=b.bno) cnt                    
            from board b, member m
 
    <!-- bno의 내림차순으로 검색 -->
            <include refid="search" />
            order by bno desc   
        <include refid="paging_footer" />
    </select>
 
    <sql id="paging_header">
<!-- 게시물을 한페이지에 10개씩 볼 수 있게하는 쿼리 윗부분-->
        select *
        from (
            select rownum as rn, A.*
            from (    
    </sql>
    <sql id="paging_footer">
<!-- 게시물을 한페이지에 10개씩 볼 수 있게하는 쿼리  아랫 부분-->
    <!-- 새로 매겨진 일련번호 1~10번 글까지 1페이지 -->
    <!-- 11~20번 글까지 2페이지.. -->
            ) A
        ) where rn between #{start} and #{end}    
    </sql>
    
    <insert id="insert">
        insert into board (bno,title,content,writer) values
        ( seq_board.nextval, #{title}, #{content}, #{writer} )
    </insert>
 
</mapper>
cs



list.jsp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<%@ include file="../include/header.jsp" %>
<script>
$(function(){ //아이디가 btnWrite인 버튼을 누르게 되면 write.do 컨트롤러로 맵핑
    $("#btnWrite").click(function(){
        location.href="${path}/board/write.do";
    });
});
 
function list(page){ //현재 페이지의 조건을 넘겨준다. +뒤에있는 것들은 검색 
    location.href="${path}/board/list.do?curPage="+page
        +"$search_option=${map.search_option}"
        +"$keyword=${map.keyword}";
}
 
</script>
</head>
<body>
<%@ include file="../include/menu.jsp" %>
<h2>게시판</h2>
 
 
<button type="button" id="btnWrite">글쓰기</button>
${map.count}개의 게시물이 있습니다.<!-- map에 저장된 개시물의 갯수를 불러옴 -->
<table border="1" width="600px">
    <tr>
        <th>번호</th>
        <th>제목</th>
        <th>이름</th>
        <th>날짜</th>
        <th>조회수</th>
    </tr>
    <!-- forEach var="개별데이터" items="집합데이터" -->
<c:forEach var="row" items="${map.list}"<!-- 컨트롤러에서 map안에 list를 넣었기 때문에 이렇게 받는다. -->
    <tr>
        <td>${row.bno}</td>
        <td>
<a href="${path}/board/view.do?bno=${row.bno}">
${row.title}
</a>
            <c:if test="${row.cnt > 0}">
                <span style="color:red;">( ${row.cnt} )</span>
            </c:if>   
        </td>
        <td>${row.name}</td>
        <td><fmt:formatDate value="${row.regdate}"
            pattern="yyyy-MM-dd HH:mm:ss"/> </td>
        <td>${row.viewcnt}</td>
    </tr>
</c:forEach>    
<!-- 페이지 네비게이션 출력 -->
    <tr>
        <td colspan="5" align="center">
            <c: forEach var = "num" begin = "1" end = "${map.pager.totPage}">
                <a href = "javascript : list ('${num}')">${num}</a>
            </c:forEach>
        </td>
    </tr>
</table>
</body>
</html>
cs



위에서 페이지 나누기 기능을 추가하기 위해서 페이지 네비게이션 부분에 페이지 나누기 코드를 추가


list.jsp 중 일부

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
<!-- 페이지 네비게이션 출력 -->
    <tr>
        <td colspan="5" align="center">
        
            <c:if test="${map.pager.curBlock > 1}">
  <a href="#" onclick="list('1')">[처음]</a>
            </c:if<!-- 현재 블록이 1블록보다 크면 (뒤쪽에 있기때문에) 처음으로 갈 수 있도록 링크를 추가 -->
        
            <c:if test="${map.pager.curBlock > 1}">
                <a href="#" onclick="list('${map.pager.prevPage}')">
                [이전]</a>
            </c:if<!-- 현재 블록이 1블록보다 크면 이전 블록으로 이동할 수 있도록 링크 추가 -->
            
            <c:forEach var="num" 
                begin="${map.pager.blockBegin}"
                end="${map.pager.blockEnd}">
                <c:choose>
                    <c:when test="${num == map.pager.curPage}">
                    
                    <!-- 현재 페이지인 경우 하이퍼링크 제거 -->
                    <!-- 현재 페이지인 경우에는 링크를 빼고 빨간색으로 처리를 한다. -->
                        <span style="color:red;">${num}</span>
                    </c:when>
                    <c:otherwise>
                        <a href="#" onclick="list('${num}')">${num}</a>
                    </c:otherwise>
                    
                </c:choose>
            </c:forEach>
            
            <c:if test="${map.pager.curBlock <= map.pager.totBlock}">
                <a href="#" 
                onclick="list('${map.pager.nextPage}')">[다음]</a>
            </c:if<!-- 현재 페이지블록이 총 페이지블록보다 작으면 다음으로 갈 수있도록 링크를 추가 -->
            
            
            <c:if test="${map.pager.curPage <= map.pager.totPage}">
                <a href="#" 
                onclick="list('${map.pager.totPage}')">[끝]</a>
            </c:if<!-- 현재 페이지블록이 총 페이지블록보다 작거나 같으면 끝으로 갈 수 있도록 링크를 추가함-->
              
            
        </td>
    </tr>
</table>
</body>
</html>
cs




컨트롤러에서 게시물 갯수를 확인하는 count 변수의 값을 boardService에서 얻어 올 수 있게 변경


BoardController.java 중 일부

1
2
3
4
5
6
7
8
9
10
11
12
13
14
    @RequestMapping("list.do"//세부적인 url pattern
        public ModelAndView list(//RequestParam으로 옵션, 키워드, 페이지의 기본값을 각각 설정해준다.
        @RequestParam(defaultValue="1"int curPage,
        @RequestParam(defaultValue="all"String search_option,
        @RequestParam(defaultValue=""String keyword)
    //defaultValue를 설정하지 않으면 null point 에러가 발생할수 있기 때문에 기본값을 설정해주어야 한다.
                        throws Exception{
        //레코드 갯수 계산
        int count = boardService.countArticle(search_option, keyword); //검색옵션과 키워드를 고려
        
        //페이지 관련 설정, 시작번호와 끝번호를 구해서 각각 변수에 저장함
        Pager pager=new Pager(count, curPage); //레코드 번호와 원하는 페이지의 번호를 주게 되면 
        int start=pager.getPageBegin();
        int end=pager.getPageEnd();
cs



BoardServiceImpl.java 중 일부

1
2
3
4
5
    @Override
    public int countArticle(
            String search_option, String keyword) throws Exception {
        return boardDao.countArticle(search_option,keyword); 
//boardDao를 호출해서 리턴
    }
cs




BoardDAO.Impl.java 중 일부

1
2
3
4
5
6
7
8
9
//레코드 갯수 계산
//검색옵션과 키워드를 같이 전달해야하기 때문에 haspmap로 묶어서 같이 전달한다.

    @Override
    public int countArticle(
            String search_option, String keyword) throws Exception {
        Map<String,String> map=new HashMap<>();
        map.put("search_option", search_option);
        map.put("keyword""%"+keyword+"%");
        return sqlSession.selectOne("board.countArticle",map);
    }
cs



boardMapper.xml 중 일부

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<!-- 다른 mapper와 중복되지 않도록 네임스페이스 기재 -->
<mapper namespace="board">
 
<!-- 레코드 갯수 계산 -->    
    <select id="countArticle" resultType="int">
        select count(*)
        from board b,member m    
        <include refid="search" />
    </select>
 
<sql id="search">
        <choose>
<!--검색옵션을 설정 글내용과, 작성자, 제목으로 검색할 수있도록 설정)
<!--검색 옵션에 따라 실행되는 구문이 틀려짐--!>
            <when test="search_option == 'all' ">
                where b.writer=m.userid 
                    and (name like '%'||#{keyword}||'%'
                     or content like '%' || #{keyword}||'%'
or title like '%'||#{keyword}||'%' )  //검색 옵션이 all이면 실행         
            </when>
            <otherwise>
                where b.writer=m.userid 
                    and ${search_option} like '%'||#{keyword}||'%' //검색 옵션이 all이 아니면 실행되는 구문
</otherwise>
        </choose>
    </sql>
cs


728x90
반응형
: