전자정부 프레임워크 게시판 만들기 연습 (5) 페이징, 검색
Pagination과 Search 클래스 추가
1. vo/Pagination.java
===================================
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;
}
}
}
==================================
2. vo/Search.java
====================================
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;
}
}
====================================
3. testMapper.xml
==================================
<?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>
********************** 오라클 코드 *************************
<!-- 게시글 삽입 -->
<insert id="insertTest" parameterType="egovframework.example.ivory.vo.TestVo">
INSERT INTO test(testId, testTitle, testContent, testName, testDate)
VALUES(TESTID.NEXTVAL,#{testTitle},#{testContent},'ivory',SYSDATE)
</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>
==================================
4. testController.java
============================
package egovframework.example.ivory.controller;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import egovframework.example.ivory.service.TestService;
import egovframework.example.ivory.vo.Search;
import egovframework.example.ivory.vo.TestVo;
@Controller
public class TestController {
@Autowired
private TestService testService;
//글보기 조회
/* @RequestMapping(value="/testList.do")
public String testListDo(TestVo testVo, Model model) throws Exception{
model.addAttribute("list", testService.selectTest(testVo));
return "test/testList";
}
//글목록페이지
@RequestMapping(value="/testList.do")
public String testListDo(TestVo testVo, Model model) throws Exception{
model.addAttribute("list", testService.selectTest(testVo));
return "test/testList";
}
*/
//글목록페이지,페이징,검색
@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";
}
//글 상세페이지
@RequestMapping(value="testDetail.do")
public String viewForm(Model model, HttpServletRequest request) throws Exception{
int testId = Integer.parseInt(request.getParameter("testId"));
TestVo testVo = testService.selectDetail(testId);
model.addAttribute("vo", testVo);
return "test/testDetail";
}
//글작성페이지
@RequestMapping(value="/testRegister.do")
public String testRegister(){
return "test/testRegister";
}
//글쓰기
@RequestMapping(value="/insertTest.do")
public String write(@ModelAttribute("testVo") TestVo testVo) throws Exception {
testService.insertTest(testVo);
return "redirect:testList.do";
}
//글수정
@RequestMapping(value="/updateTest.do")
public String updateTest(@ModelAttribute("testVo") TestVo testVo) throws Exception {
testService.updateTest(testVo);
return "redirect:testDetail.do?testId="+testVo.getTestId();
}
//글삭제
@RequestMapping(value="/deleteTest.do")
public String deleteTest(HttpServletRequest request) throws Exception {
int testId = Integer.parseInt(request.getParameter("testId"));
testService.deleteTest(testId);
return "redirect:testList.do";
}
}
============================
selectTest에 보내주는 객체가 다르니 참고!! (service,serviceImpl,dao.... 에 있는 메서드도 바꿔주어야함)
5. testService.java
==============================
package egovframework.example.ivory.service;
import java.util.List;
import egovframework.example.ivory.vo.TestVo;
import egovframework.example.ivory.vo.Search;
public interface TestService {
public List<TestVo> selectTest(Search search) throws Exception;
//public List<TestVo> selectTest(TestVo testVo) 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;
}
=============================
6. testServiceImpl.java
=============================
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.TestVo;
import egovframework.example.ivory.vo.Search;
@Service
public class TestServiceImpl implements TestService{
@Autowired
private TestDao testDao;
/* @Override
public List<TestVo> selectTest(TestVo testVo) throws Exception {
return testDao.selectTest(testVo);
}*/
@Override
public List<TestVo> selectTest(Search search) throws Exception {
return testDao.selectTest(search);
}
@Override
public int getBoardListCnt(Search search) throws Exception {
return testDao.getBoardListCnt(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);
}
}
=============================
7. testDao.java
===============================
package egovframework.example.ivory.dao;
import java.util.List;
import egovframework.example.ivory.vo.TestVo;
import egovframework.example.ivory.vo.Search;
public interface TestDao {
public List<TestVo> selectTest(Search search) throws Exception;
// public List<TestVo> selectTest(TestVo testVo) 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;
}
===============================
8. testDaoImpl.java
============================
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.TestVo;
import egovframework.example.ivory.vo.Search;
@Repository
public class TestDaoImpl implements TestDao {
@Autowired
private SqlSession sqlSession;
/* @Override
public List<TestVo> selectTest(TestVo testVo) throws Exception {
TestMapper mapper = sqlSession.getMapper(TestMapper.class);
return mapper.selectTest(testVo);
}*/
@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);
}
}
============================
9. TestMapper.java
============================
package egovframework.example.ivory.service;
import java.util.List;
import egovframework.example.ivory.vo.TestVo;
import egovframework.example.ivory.vo.Search;
//Mapper namespace 와 ID를 연결할 Interface 를 두어서 interface를 호출하는 방법.
//Mybatis 매핑XML에 기재된 SQL을 호출하기 위한 인터페이스이다.
//SQL id는 인터페이스에 정의된 메서드명과 동일하게 작성한다
public interface TestMapper {
//List<TestVo> selectTest(TestVo testVo) throws Exception;
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;
}
============================
10. testList.jsp
============================
<%@ 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">
a {
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>
=============================
서버 재실행
ㄴ testList.jsp 메인 화면
ㄴ 페이지 번호 이동
ㄴ 다음 버튼 눌렀을때
ㄴ 제목을 테스트로 검색 했을때
ㄴ 내용을 '검색어' 로 했을때
ㄴ 작성자를 'ddd' 로 검색 했을때
'IT 및 공부 > Spring & JSP & PHP' 카테고리의 다른 글
DAO(service), DTO(vo), 커넥션풀 의 각각의 역할 (0) | 2022.08.22 |
---|---|
전자정부 프레임워크 게시판 만들기 연습 (6) 파일 업로드, 다운로드 (0) | 2022.08.12 |
전자정부 프레임워크 게시판 만들기 연습 (4) 글 상세보기, 수정, 삽입, 삭제 (0) | 2022.08.11 |
전자정부 프레임워크 게시판 만들기 연습 (3) MariaDB연동, 게시판 리스트 출력 (0) | 2022.08.11 |
전자정부 프레임워크 게시판 만들기 연습 (2) 기초 설정 및 경로 설정 (0) | 2022.08.11 |