본문 바로가기

study/java

전자정부프레임워크기반 게시판 만들기 (5) 페이징,검색

Pagination과 Search 클래스 추가

 

페이징,검색 참고 블로그 : freehoon.tistory.com/112?category=735500

 

Spring 블로그 만들기 - 9. 페이징(pagination)

이 포스팅의 샘플 게시판 개발 환경은 MAC OS, STS, OpenJDK11 입니다. 페이징 처리에 대한 포스팅은 아래와 같은 순서로 진행합니다. 페이징 테스트를 위한 데이터 만들기 Pagination 클래스 만들기 게

freehoon.tistory.com

 

vo/Pagination.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
139
140
141
142
143
144
145
146
147
148
149
150
package egovframework.example.ivory.vo;
 
public class Pagination {
    
    private int listSize = 10//초기값으로 한 페이지당 보여질 게시글 개수
    
    private int rangeSize = 5//초기값으로 페이지 범위에 보여질 페이지 개수
    
    private int page; //현재 페이지 번호
    
    private int range; //현재 페이지 범위
    
    private int listCnt; //전체 게시글의 개수
    
    private int pageCnt; //전체 페이지 범위의 개수
    
    private int startPage; //각 페이지 범위 시작 번호
    
    private int startList; //게시판 시작번호
    
    private int endPage; //각 페이지 범위 끝 번호
    
    private boolean prev; //이전페이지
    
    private boolean next; //다음페이지
 
    public int getListSize() {
        return listSize;
    }
 
    public void setListSize(int listSize) {
        this.listSize = listSize;
    }
 
    public int getRangeSize() {
        return rangeSize;
    }
 
    public void setRangeSize(int rangeSize) {
        this.rangeSize = rangeSize;
    }
 
    public int getPage() {
        return page;
    }
 
    public void setPage(int page) {
        this.page = page;
    }
 
    public int getRange() {
        return range;
    }
 
    public void setRange(int range) {
        this.range = range;
    }
 
    public int getListCnt() {
        return listCnt;
    }
 
    public void setListCnt(int listCnt) {
        this.listCnt = listCnt;
    }
 
    public int getPageCnt() {
        return pageCnt;
    }
 
    public void setPageCnt(int pageCnt) {
        this.pageCnt = pageCnt;
    }
 
    public int getStartPage() {
        return startPage;
    }
 
    public void setStartPage(int startPage) {
        this.startPage = startPage;
    }
 
    public int getStartList() {
        return startList;
    }
 
    public void setStartList(int startList) {
        this.startList = startList;
    }
 
    public int getEndPage() {
        return endPage;
    }
 
    public void setEndPage(int endPage) {
        this.endPage = endPage;
    }
 
    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 void pageInfo(int page, int range, int listCnt){
        //현재페이지
        this.page = page;
        
        //현재페이지 범위
        this.range = range;
        
        //게시글 개수
        this.listCnt = listCnt;
        
        //전체 페이지 개수
        this.pageCnt = (int)Math.ceil(listCnt/listSize);
        
        //시작페이지
        this.startPage = (range - 1* rangeSize + 1;
        
        //끝페이지
        this.endPage = range * rangeSize;
        
        //게시판 시작 번호
        this.startList = (page - 1* listSize;
        
        //이전 버튼 상태
        this.prev = range == 1 ? false : true;
        
        //다음 버튼 상태
        this.next = endPage > pageCnt ? false : true;
        
        if(this.endPage > this.pageCnt){
            this.endPage = this.pageCnt;
            this.next = false;
        }
        
    }
}
 
cs

 

vo/Search.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package egovframework.example.ivory.vo;
 
public class Search extends Pagination {
    
    private String searchType;
    private String keyword;
    
    public String getSearchType() {
        return searchType;
    }
    public void setSearchType(String searchType) {
        this.searchType = searchType;
    }
    public String getKeyword() {
        return keyword;
    }
    public void setKeyword(String keyword) {
        this.keyword = keyword;
    }
    
}
 
cs

 

testMapper.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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
<?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="egovframework.example.ivory.service.TestMapper">
    
    <!-- 게시글 목록 조회 -->
    <select id="selectTest" resultType="egovframework.example.ivory.vo.TestVo">
        SELECT * FROM test
        <where>
            <if test="searchType=='testTitle' and keyword != null and keyword !=''">
                AND testTitle like CONCAT('%',#{keyword},'%')
            </if>
            <if test="searchType=='testContent' and keyword != null and keyword !=''">
                AND testContent like CONCAT('%',#{keyword},'%')
            </if>
            <if test="searchType=='testName' and keyword != null and keyword !=''">
                AND testName like CONCAT('%',#{keyword},'%')
            </if>
        </where>
        ORDER BY testId DESC
        LIMIT #{startList}, #{listSize}
    </select>
    
    <!-- 게시글 갯수 -->
    <select id="getBoardListCnt" resultType="Integer">
        SELECT count(*) as listCnt
        FROM test
        <where>
            <if test="keyword != null and keyword != ''">
                <if test="searchType=='testTitle'">
                    AND testTitle like CONCAT('%',#{keyword},'%')
                </if>
                <if test="searchType=='testContent'">
                    AND testContent like CONCAT('%',#{keyword},'%')
                </if>
                <if test="searchType=='testName'">
                    AND testName like CONCAT('%',#{keyword},'%')
                </if>
            </if>
        </where>
    </select>
    
    <!-- 게시글 상세보기 -->
    <select id="selectDetail" parameterType="Integer" resultType="egovframework.example.ivory.vo.TestVo">
        SELECT * FROM test
        WHERE testId = #{testId}
    </select>
    
    <!-- 게시글 삽입 -->
    <insert id="insertTest" parameterType="egovframework.example.ivory.vo.TestVo">
        INSERT INTO test(testTitle, testContent, testName, testDate)
        VALUES(#{testTitle},#{testContent},'ivory',now())
    </insert>
    
    <!-- 게시글 수정 -->
    <update id="updateTest" parameterType="egovframework.example.ivory.vo.TestVo">
        UPDATE test SET
        testTitle = #{testTitle}, testContent = #{testContent}
        WHERE testId = #{testId}
    </update>
    
    <!-- 게시글 삭제 -->
    <delete id="deleteTest" parameterType="Integer">
        DELETE FROM test
        WHERE testId = #{testId}
    </delete>
</mapper>
cs

 

testController.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
    //글목록페이지,페이징,검색
    @RequestMapping(value="/testList.do")
    public String testListDo(Model model
            ,@RequestParam(required=false,defaultValue="1")int page
            ,@RequestParam(required=false,defaultValue="1")int range
            ,@RequestParam(required=false,defaultValue="testTitle")String searchType
            ,@RequestParam(required=false)String keyword
            ,@ModelAttribute("search")Search search) throws Exception{
        
        //검색
        model.addAttribute("search", search);
        search.setSearchType(searchType);
        search.setKeyword(keyword);
        
        //전체 개시글 개수
        int listCnt = testService.getBoardListCnt(search);
        
        //검색 후 페이지
        search.pageInfo(page, range, listCnt);
        //페이징
        model.addAttribute("pagination", search);
        //게시글 화면 출력
        model.addAttribute("list", testService.selectTest(search));
        
//        model.addAttribute("list", testService.selectTest(testVo));
        
        return "test/testList";
    }
cs

selectTest에 보내주는 객체가 다르니 참고!! (service,serviceImpl,dao.... 에 있는 메서드도 바꿔주어야함)

 

testService.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package egovframework.example.ivory.service;
 
import java.util.List;
 
import egovframework.example.ivory.vo.Search;
import egovframework.example.ivory.vo.TestVo;
 
public interface TestService {
 
    public List<TestVo> selectTest(Search search) throws Exception;
 
    public void insertTest(TestVo testVo) throws Exception;
 
    public TestVo selectDetail(int testId) throws Exception;
 
    public void updateTest(TestVo testVo) throws Exception;
 
    public void deleteTest(int testId) throws Exception;
 
    public int getBoardListCnt(Search search) throws Exception;
 
}
 
cs

 

testServiceImpl.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
package egovframework.example.ivory.service.impl;
 
import java.util.List;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
 
import egovframework.example.ivory.dao.TestDao;
import egovframework.example.ivory.service.TestService;
import egovframework.example.ivory.vo.Search;
import egovframework.example.ivory.vo.TestVo;
 
@Service
public class TestServiceImpl implements TestService{
 
    @Autowired
    private TestDao testDao;
    
    @Override
    public List<TestVo> selectTest(Search search) throws Exception {
        return testDao.selectTest(search);
    }
 
    @Override
    public void insertTest(TestVo testVo) throws Exception {
        testDao.insertTest(testVo);
    }
 
    @Override
    public TestVo selectDetail(int testId) throws Exception {
        return testDao.selectDetail(testId);
    }
 
    @Override
    public void updateTest(TestVo testVo) throws Exception {
        testDao.updateTest(testVo);
    }
 
    @Override
    public void deleteTest(int testId) throws Exception {
        testDao.deleteTest(testId);
    }
 
    @Override
    public int getBoardListCnt(Search search) throws Exception {
        return testDao.getBoardListCnt(search);
    }
 
}
 
cs

 

testDao.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package egovframework.example.ivory.dao;
 
import java.util.List;
 
import egovframework.example.ivory.vo.Search;
import egovframework.example.ivory.vo.TestVo;
 
public interface TestDao {
 
    public List<TestVo> selectTest(Search search) throws Exception;
 
    public void insertTest(TestVo testVo) throws Exception;
 
    public TestVo selectDetail(int testId)throws Exception;
 
    public void updateTest(TestVo testVo) throws Exception;
 
    public void deleteTest(int testId) throws Exception;
 
    public int getBoardListCnt(Search search) throws Exception;
 
}
 
cs

 

testDaoImpl.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
package egovframework.example.ivory.dao.impl;
 
import java.util.List;
 
import org.apache.ibatis.session.SqlSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
 
import egovframework.example.ivory.dao.TestDao;
import egovframework.example.ivory.service.TestMapper;
import egovframework.example.ivory.vo.Search;
import egovframework.example.ivory.vo.TestVo;
 
@Repository
public class TestDaoImpl implements TestDao {
 
    @Autowired
    private SqlSession sqlSession;
    
    @Override
    public List<TestVo> selectTest(Search search) throws Exception {
        TestMapper mapper = sqlSession.getMapper(TestMapper.class);
        return mapper.selectTest(search);
    }
 
    @Override
    public void insertTest(TestVo testVo) throws Exception {
        TestMapper mapper = sqlSession.getMapper(TestMapper.class);
        mapper.insertTest(testVo);
    }
 
    @Override
    public TestVo selectDetail(int testId) throws Exception {
        TestMapper mapper = sqlSession.getMapper(TestMapper.class);
        return mapper.selectDetail(testId);
    }
 
    @Override
    public void updateTest(TestVo testVo) throws Exception {
        TestMapper mapper = sqlSession.getMapper(TestMapper.class);
        mapper.updateTest(testVo);
    }
 
    @Override
    public void deleteTest(int testId) throws Exception {
        TestMapper mapper = sqlSession.getMapper(TestMapper.class);
        mapper.deleteTest(testId);
    }
 
    @Override
    public int getBoardListCnt(Search search) throws Exception {
        TestMapper mapper = sqlSession.getMapper(TestMapper.class);
        return mapper.getBoardListCnt(search);
    }
 
}
 
cs

 

TestMapper.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
package egovframework.example.ivory.service;
 
import java.util.List;
 
import egovframework.example.ivory.vo.Search;
import egovframework.example.ivory.vo.TestVo;
//Mapper namespace 와 ID를 연결할 Interface 를 두어서 interface를 호출하는 방법.
//Mybatis 매핑XML에 기재된 SQL을 호출하기 위한 인터페이스이다.
//SQL id는 인터페이스에 정의된 메서드명과 동일하게 작성한다
public interface TestMapper {
 
    public List<TestVo> selectTest(Search search) throws Exception;
 
    public void insertTest(TestVo testVo) throws Exception;
 
    public TestVo selectDetail(int testId) throws Exception;
 
    public void updateTest(TestVo testVo) throws Exception;
 
    public void deleteTest(int testId) throws Exception;
 
    public int getBoardListCnt(Search search) throws Exception;
 
}
 
cs

 

testList.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
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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Board List</title>
<!-- Bootstrap CSS -->
<link
    rel="stylesheet"
    integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1"
    crossorigin="anonymous">
<style type="text/css">
{
    text-decoration: auto;
}
.row>*{
    width:auto;
}
</style>
</head>
<body>
    <br />
    <h1 class="text-center">Board List</h1>
    <br />
    <br />
    <div class="container">
        <table class="table table-hover table-striped text-center"
            style="border: 1px solid;">
            <colgroup>
                <col width="10%" />
                <col width="50%" />
                <col width="20%" />
                <col width="20%" />
            </colgroup>
            <thead>
                <tr>
                    <th>번호</th>
                    <th>제목</th>
                    <th>작성자</th>
                    <th>등록일자</th>
                </tr>
            </thead>
 
            <tbody>
                <c:forEach items="${list }" var="result">
                    <tr>
                        <td>${result.testId}</td>
                        <td><a href="testDetail.do?testId=${result.testId}">${result.testTitle}</a></td>
                        <td>${result.testName}</td>
                        <td>${result.testDate}</td>
                    </tr>
                </c:forEach>
            </tbody>
        </table>
        <!-- pagination start -->
        <div id="paginationBox" class="pagination1">
            <ul class="pagination" style="justify-content: center;">
 
                <c:if test="${pagination.prev}">
                    <li class="page-item"><a class="page-link" href="#"
                        onClick="fn_prev('${pagination.page}', '${pagination.range}', '${pagination.rangeSize}', '${pagination.listSize}'
                    ,'${search.searchType}', '${search.keyword}')">이전</a></li>
                </c:if>
 
                <c:forEach begin="${pagination.startPage}" end="${pagination.endPage}" var="testId">
                    <li class="page-item <c:out value="${pagination.page == testId ? 'active' : ''}"/> ">
                    <a class="page-link" href="#"
                        onClick="fn_pagination('${testId}', '${pagination.range}', '${pagination.rangeSize}', '${pagination.listSize}'
                     ,'${search.searchType}', '${search.keyword}')">
                            ${testId} </a></li>
                </c:forEach>
 
                <c:if test="${pagination.next}">
                    <li class="page-item"><a class="page-link" href="#"
                        onClick="fn_next('${pagination.range}', '${pagination.range}', '${pagination.rangeSize}', '${pagination.listSize}'
                    ,'${search.searchType}', '${search.keyword}')">다음</a></li>
                </c:if>
            </ul>
        </div>
        <!-- pagination end -->
        <hr />
        
        <a class="btn btn-outline-info" style="float: right" href="testRegister.do">글쓰기</a>
 
        <!-- search start -->
        <div class="form-group row">
 
            <div class="w100" style="padding-right: 10px">
                <select class="form-control form-control-sm" name="searchType" id="searchType">
                    <option value="testTitle">제목</option>
                    <option value="testContent">내용</option>
                    <option value="testName">작성자</option>
                </select>
            </div>
 
            <div class="w300" style="padding-right: 10px">
                <input type="text" class="form-control form-control-sm" name="keyword" id="keyword">
            </div>
 
            <div>
                <button class="btn btn-sm btn-primary" name="btnSearch" id="btnSearch">검색</button>
            </div>
 
        </div>
        <!-- search end -->
    
    </div>
    <br>
    <script
        integrity="sha384-ygbV9kiqUc6oa4msXn9868pTtWMgiQaeYH7/t7LECLbyPA2x65Kgf80OJFdroafW"
        crossorigin="anonymous"></script>
 
    <script
        integrity="sha384-q2kxQ16AaE6UbzuKqyBE9/u/KzioAlnx2maXQHiDX9d4/zp8Ok3f+M7DPm+Ib6IU"
        crossorigin="anonymous"></script>
    <script
        integrity="sha384-pQQkAEnwaBkjpqZ8RU1fF1AKtTcHJwFl3pblpTlHXybJjHpMYo79HY3hIi4NKxyj"
        crossorigin="anonymous"></script>
</body>
    <script type="text/javascript">
    //이전 버튼 이벤트
    //5개의 인자값을 가지고 이동 testList.do
    //무조건 이전페이지 범위의 가장 앞 페이지로 이동
    function fn_prev(page, range, rangeSize, listSize, searchType, keyword) {
            
        var page = ((range - 2* rangeSize) + 1;
        var range = range - 1;
            
        var url = "/testList.do";
        url += "?page=" + page;
        url += "&range=" + range;
        url += "&listSize=" + listSize;
        url += "&searchType=" + searchType;
        url += "&keyword=" + keyword;
        location.href = url;
        }
 
 
    //페이지 번호 클릭
    function fn_pagination(page, range, rangeSize, listSize, searchType, keyword) {
 
        var url = "/testList.do";
            url += "?page=" + page;
            url += "&range=" + range;
            url += "&listSize=" + listSize;
            url += "&searchType=" + searchType;
            url += "&keyword=" + keyword; 
 
            location.href = url;    
        }
 
    //다음 버튼 이벤트
    //다음 페이지 범위의 가장 앞 페이지로 이동
    function fn_next(page, range, rangeSize, listSize, searchType, keyword) {
        var page = parseInt((range * rangeSize)) + 1;
        var range = parseInt(range) + 1;            
        var url = "/testList.do";
            url += "?page=" + page;
            url += "&range=" + range;
            url += "&listSize=" + listSize;
            url += "&searchType=" + searchType;
            url += "&keyword=" + keyword;
            location.href = url;
        }
        
    // 검색
    $(document).on('click''#btnSearch'function(e){
        e.preventDefault();
        var url = "/testList.do";
        url += "?searchType=" + $('#searchType').val();
        url += "&keyword=" + $('#keyword').val();
        location.href = url;
        console.log(url);
 
    });    
 
    </script>
</html>
cs

 

testList.jsp 메인

 

페이지 번호 이동

 

다음 버튼 눌렀을때

 

제목을 '테스트'로 검색했을때

 

내용을 '검색어'로 검색했을때



출처: https://ivory-room.tistory.com/63?category=875739 [개발로 자기개발]