ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 전자정부프레임워크기반 게시판 만들기 (5) 페이징,검색
    DEV/Spring 2020. 12. 30. 15:06

    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
        href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css"
        rel="stylesheet"
        integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1"
        crossorigin="anonymous">
    <script src="https://code.jquery.com/jquery-1.12.4.js"></script>
    <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
            src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/js/bootstrap.bundle.min.js"
            integrity="sha384-ygbV9kiqUc6oa4msXn9868pTtWMgiQaeYH7/t7LECLbyPA2x65Kgf80OJFdroafW"
            crossorigin="anonymous"></script>
     
        <script
            src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.5.4/dist/umd/popper.min.js"
            integrity="sha384-q2kxQ16AaE6UbzuKqyBE9/u/KzioAlnx2maXQHiDX9d4/zp8Ok3f+M7DPm+Ib6IU"
            crossorigin="anonymous"></script>
        <script
            src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/js/bootstrap.min.js"
            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 메인

     

    페이지 번호 이동

     

    다음 버튼 눌렀을때

     

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

     

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

    댓글

Designed by Tistory.