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.test.service.TestMapper">

	<!--게시글 목록 조회 -->
	<select id="selectTest" resultType="TestVO">
		SELECT
		*
		FROM test
		<trim prefix="WHERE" prefixOverrides="AND|OR">
			<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>
		</trim>
		ORDER BY
		testId DESC
		LIMIT #{startList}, #{listSize}
	</select>

	<!-- 전체 글의 개수를 읽어 오는 SQL문 -->
	<select id="getBoardListCnt" resultType="int">
		SELECT
		count(*) as
		listCnt
		FROM
		test
		<trim prefix="WHERE" prefixOverrides="AND|OR">
			<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>
		</trim>
	</select>

	<!--게시글 삽입 -->
	<insert id="insertTest" parameterType="TestVO">
		<![CDATA[
		INSERT INTO test(testTitle, testContent, testName, testDate)
		VALUES(#{testTitle}, #{testContent}, '밥샵', now())
		]]>
	</insert>

	<!--게시글 클릭시 detailView -->
	<select id="selectDetail"
		parameterType="egovframework.example.test.domain.TestVO"
		resultType="egovframework.example.test.domain.TestVO">
		<![CDATA[
			SELECT *
			FROM test
			WHERE testId = #{testId}
		]]>
	</select>

	<!--게시글 업데이트 -->
	<update id="updateTest">
		update test set
		testTitle = #{testTitle}
		,testContent =
		#{testContent}
		where
		testId = #{testId}
	</update>

	<!--게시글 삭제 -->
	<delete id="deleteTest">
		delete from test
		where
		testId = #{testId}
	</delete>
</mapper> 





Pagination과 Search 추가


Pagination

package egovframework.example.test.domain;

public class Pagination {

	private int listSize = 10; // 초기값으로 목록개수를 10으로 셋팅 한 페이지당 보여질 리스트의 개수

	private int rangeSize = 5; // 초기값으로 페이지범위를 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 getRangeSize() {

		return 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 getStartPage() {

		return startPage;

	}

	public void setStartPage(int startPage) {

		this.startPage = startPage;

	}

	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 int getListSize() {

		return listSize;

	}

	public void setListSize(int listSize) {

		this.listSize = listSize;

	}

	public int getListCnt() {

		return listCnt;

	}

	public void setListCnt(int listCnt) {

		this.listCnt = listCnt;

	}

	public int getStartList() {

		return startList;

	}

	// 첫번째 인자 page 는 현재 페이지 정보, 두번째 인자 range 는 현재 페이지 범위 정보, 세번째 인자 listCnt는 게시물의 총 개수
	public void pageInfo(int page, int range, int listCnt) {

		this.page = page;

		this.range = range;

		this.listCnt = listCnt;

		// 전체 페이지수
		this.pageCnt = (int) Math.ceil((double) 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;
		}
	}
}

Search

package egovframework.example.test.domain;

//Search 클래스가 Pagination 클래스를 상속 받았으므로 기존 Pagination의 특성을 그대로 사용 할 수 있다.
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;
	}
}

TestController

package egovframework.example.test.web;


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 org.springframework.web.servlet.mvc.support.RedirectAttributes;

import egovframework.example.test.domain.Search;
import egovframework.example.test.domain.TestVO;
import egovframework.example.test.service.TestService;

@Controller
public class TestController {

	@Autowired
	private TestService testServiceImpl;

	// 글 목록 리스트, 페이징, 검색
	@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);
		
		// 전체 게시글 개수를 얻어와 listCnt에 저장
		int listCnt = testServiceImpl.getBoardListCnt(search);

		//검색
		search.pageInfo(page, range, listCnt);
		//페이징
		model.addAttribute("pagination", search);
		//게시글 화면 출력
		model.addAttribute("list", testServiceImpl.selectTest(search));

		return "test/testList";
	}

	// 글 작성 클릭시 글 작성 페이지로 이동
	@RequestMapping(value = "/testRegister.do")
	public String testRegister() {
		return "test/testRegister";
	}

	// 글 작성 버튼 구현
	@RequestMapping(value = "/insertTest.do")
	public String write(@ModelAttribute("testVO") TestVO testVO, RedirectAttributes rttr) throws Exception {
		testServiceImpl.insertTest(testVO);
		return "redirect:testList.do";
	}

	// HttpServletRequest 객체안에 모든 데이터들이 들어가는데 getParameter메소드로 testId 원하는 데이터 가져옴
	// 제목 클릭 시 상세보기
	@RequestMapping(value = "/testDetail.do")
	public String viewForm(@ModelAttribute("testVO") TestVO testVO, Model model, HttpServletRequest request)
			throws Exception {

		int testId = Integer.parseInt(request.getParameter("testId"));
		testVO.setTestId(testId);

		TestVO resultVO = testServiceImpl.selectDetail(testVO);
		model.addAttribute("result", resultVO);

		return "test/testDetail";
	}

	// 수정하기
	@RequestMapping(value = "/updateTest.do")
	public String updateTest(@ModelAttribute("testVO") TestVO testVO, HttpServletRequest request) throws Exception {
		testServiceImpl.updateTest(testVO);
		return "redirect:testList.do";
	}

	// 삭제하기
	@RequestMapping(value = "/deleteTest.do")
	public String deleteTest(@ModelAttribute("testVO") TestVO testVO) throws Exception {
		testServiceImpl.deleteTest(testVO);
		return "redirect:testList.do";
	}

}

TestService

package egovframework.example.test.service;

import java.util.List;

import egovframework.example.test.domain.Search;
import egovframework.example.test.domain.TestVO;

public interface TestService {

	public List<TestVO> selectTest(Search search) throws Exception;

	public void insertTest(TestVO testVO)throws Exception;

	public TestVO selectDetail(TestVO testVO) throws Exception;

	public void updateTest(TestVO testVO) throws Exception;

	public void deleteTest(TestVO testVO) throws Exception;
	
	//총 게시글 개수 확인
	public int getBoardListCnt(Search search) throws Exception;

}

TestServiceImpl

package egovframework.example.test.service.impl;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import egovframework.example.test.dao.TestDAO;
import egovframework.example.test.domain.Search;
import egovframework.example.test.domain.TestVO;
import egovframework.example.test.service.TestService;

@Service("testServiceImpl")
public class TestServiceImpl implements TestService {

	@Autowired
	private TestDAO testDAOService;

	@Override
	public List<TestVO> selectTest(Search search) throws Exception {
		return testDAOService.selectTest(search);
	}

	@Override
	public void insertTest(TestVO testVO) throws Exception {
		testDAOService.insertTest(testVO);
	}

	@Override
	public TestVO selectDetail(TestVO testVO) throws Exception {
		/*
		 * TestVO resultVO = testDAOService.selectDetail(testVO); return resultVO;
		 */
		return testDAOService.selectDetail(testVO);
	}

	@Override
	public void updateTest(TestVO testVO) throws Exception {
		testDAOService.updateTest(testVO);
	}

	@Override
	public void deleteTest(TestVO testVO) throws Exception {
		testDAOService.deleteTest(testVO);
	}
	// 총 게시글 개수 확인

	@Override
	public int getBoardListCnt(Search search) throws Exception {
		return testDAOService.getBoardListCnt(search);
	}

}

TestDAO

package egovframework.example.test.dao;

import java.util.List;

import egovframework.example.test.domain.Search;
import egovframework.example.test.domain.TestVO;

public interface TestDAO {

	List<TestVO> selectTest(Search search) throws Exception;

	void insertTest(TestVO testVO) throws Exception;
	
	TestVO selectDetail(TestVO testVO) throws Exception;

	void updateTest(TestVO testVO) throws Exception;

	void deleteTest(TestVO testVO) throws Exception;
	
	//총 게시글 개수 확인
	public int getBoardListCnt(Search search) throws Exception;

}

TestDAOService

package egovframework.example.test.dao;

import java.util.List;

import org.apache.ibatis.session.SqlSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import egovframework.example.test.domain.Search;
import egovframework.example.test.domain.TestVO;
import egovframework.example.test.service.TestMapper;

@Service("testDAOService")
public class TestDAOService 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(TestVO testVO) throws Exception {
		TestMapper mapper = sqlSession.getMapper(TestMapper.class);
		return mapper.selectDetail(testVO);
	}

	@Override
	public void updateTest(TestVO testVO) throws Exception {
		TestMapper mapper = sqlSession.getMapper(TestMapper.class);
		mapper.updateTest(testVO);
	}

	@Override
	public void deleteTest(TestVO testVO) throws Exception {
		TestMapper mapper = sqlSession.getMapper(TestMapper.class);
		mapper.deleteTest(testVO);
	}

	// 총 게시글 개수 확인
	@Override
	public int getBoardListCnt(Search search) throws Exception {
		TestMapper mapper = sqlSession.getMapper(TestMapper.class);
		return mapper.getBoardListCnt(search);
	}
}

TestMapper.java

package egovframework.example.test.service;

import java.util.List;

import egovframework.example.test.domain.Search;
import egovframework.example.test.domain.TestVO;


public interface TestMapper {

	// 게시물 리스트 조회
	public List<TestVO> selectTest(Search search) throws Exception;

	// 게시물 작성
	public void insertTest(TestVO testVO) throws Exception;

	// 게시물 조회
	public TestVO selectDetail(TestVO testVO) throws Exception;

	// 게시물 수정
	public void updateTest(TestVO testVO) throws Exception;

	// 게시물 삭제
	public void deleteTest(TestVO testVO) throws Exception;

	// 총 게시글 개수 확인
	public int getBoardListCnt(Search search) throws Exception;
}

testList.jsp

<%@ page language="java" contentType="text/html;charset=UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@taglib uri="http://www.springframework.org/tags" prefix="spring"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>
<html>

<head>
<!-- Bootstrap CSS -->

<link rel="stylesheet"
	href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css"
	integrity="sha384-GJzZqFGwb1QTTN6wy59ffF1BuGJpLSa9DkKMp0DgiMDm4iYMj70gZWKYbI706tWS"
	crossorigin="anonymous">

<link href="/css/test/test.css" rel="stylesheet" type="text/css">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>

</head>

<body>

	<h1>게시판List</h1>

	<div class="testlist">
		<form id="boardForm" name="boardForm" method="post">
			<table class="list_table">
				<colgroup>
					<col width="20%" />
					<col width="50%" />
					<col width="15%" />
					<col width="15%" />
				</colgroup>
				<tbody>
				<thead>

					<tr>
						<th>번호</th>
						<th>제목</th>
						<th>작성자</th>
						<th>등록일자</th>
					</tr>
				</thead>

				<!-- jstl 데이터베이스를 검색해 넘겨 받은 list 를 result 라는 이름으로 순차적으로 실행을 시키게 됨  java의 for문같이 순차적으로 실행시킴-->

				<c:forEach items="${list}" var="result">
					<tr>
						<td><c:out value="${result.testId}" /></td>
						<td><a href='#' onClick='fn_view(${result.testId})'><c:out
									value="${result.testTitle }" /></a></td>
						<td><c:out value="${result.testName}" /></td>
						<td><c:out value="${result.testDate}" /></td>
					</tr>
				</c:forEach>
				</tbody>
			</table>
		</form>
	</div>
	<div>
		<button id="btn_write" type="button" class="btn_write">글작성</button>
	</div>
	<br>
	<!-- pagination{s} -->

	<div id="paginationBox" class="pagination1">
		<ul class="pagination">

			<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{e} -->



	<!-- search{s} -->

	<div class="form-group row justify-content-center">

		<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"
				<%-- value="${pagination.keyword}" --%> 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{e} -->


	<!-- 페이지 목록 갯수   -->
	<div class="form-group row justify-content-center">
		<p>게시판 목록 갯수</p>
		<div class="w100" style="padding-right: 10px">
			<select class="form-control form-control-sm" name="searchType"
				id="listSize" onchange="page(1)">
				<option value="10"
					<c:if test="${pagination.getListSize() == 10 }">selected="selected"</c:if>>10개</option>
				<option value="15"
					<c:if test="${pagination.getListSize() == 15 }">selected="selected"</c:if>>15개</option>
				<option value="20"
					<c:if test="${pagination.getListSize() == 20 }">selected="selected"</c:if>>20개</option>
			</select>
		</div>

	</div>
</body>
<script type="text/javascript">
	//글 작성 버튼 클릭 시 testRegister로 이동
	$("#btn_write").click(function javascript_onclikc() {
		$(location).attr('href', 'testRegister.do');

	});
	
	//글조회
	//	어떤 게시물을 클릭했는지 게시물의 번호(testId)를 넘겨 줘야 함 따라서 게시물 클릭 이벤트에서 게시물의 번호를 인자 값으로 받습니다.
	//  get 방식으로 데이터를 전송합니다. 따라서 ? 연산자를 사용해 testId를 주소 뒤에 붙여 줍니다
	function fn_view(testId){
    
  	  var form = document.getElementById("boardForm");
  	  var url = "<c:url value='/testDetail.do'/>";
  	  url = url + "?testId=" + testId;
    
 	   form.action = url;    
 	   form.submit(); 
	}
	//이전 버튼 이벤트
	//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 = url + "?page=" + page;
		url = url + "&range=" + range;
		url = url + "&listSize=" + listSize;
		url = url + "&searchType=" + searchType;
		url = url + "&keyword=" + keyword;
		location.href = url;
		}

	  //페이지 번호 클릭

	function fn_pagination(page, range, rangeSize, listSize, searchType, keyword) {

		var url = "/testList.do";
			url = url + "?page=" + page;
			url = url + "&range=" + range;
			url = url + "&listSize=" + listSize;
			url = url + "&searchType=" + searchType;
			url = 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 = url + "?page=" + page;
			url = url + "&range=" + range;
			url = url + "&listSize=" + listSize;
			url = url + "&searchType=" + searchType;
			url = url + "&keyword=" + keyword;
			location.href = url;
		}
		
		
	/* $는 jQuery를 시작하는 명령어로
	$(DOM요소) 와 같은 명령어로 각 요소에 접근 할 수 있다.
	e.preventDefault(); 는 버튼 고유의 기능을 막는 명령어 */ 
		
		// 검색
	$(document).on('click', '#btnSearch', function(e){
		e.preventDefault();
		var url = "/testList.do";
		url = url + "?searchType=" + $('#searchType').val();
		url = url + "&keyword=" + $('#keyword').val();
		url = url + "&listSize=" + $('#listSize').val();
		location.href = url;
		console.log(url);

	});	

	/*한페이지당 게시물 */
	function page(testId){
	  var startPage = testId;
	  var listSize = $("#listSize option:selected").val();
		
	  if(listSize == 10){
		  var url="/testList.do?startPage="+startPage+"&listSize="+listSize
	  }else if(listSize == 15){
		  var url ="/testList.do?startPage="+startPage+"&listSize="+listSize
	  }else if(listSize == 20){
	      var url="/testList.do?startPage="+startPage+"&listSize="+listSize
	 
	  }
	  location.href = url;
	}
</script>
</html>

페이징과 검색 selectbox가 다 기능하는 모습입니다. 목록 갯수 변경 후 검색, 페이징 등

+ Recent posts