ALTER PROCEDURE [dbo].[USP_GET_BOARD]
@CURRENT AS int,
@ROW AS int
AS
BEGIN
SELECT
*
FROM [dbo].[User]
order by [Num] desc
OFFSET (@CURRENT-1) *@ROW ROWS
FETCH NEXT @ROW ROWS ONLY
END
order by 절은 필수입니다.
ORDER BY를 통해 정렬 기준을 정한 뒤 OFFSET을 통해 건너 뛸 행의 수를 먼저 설정하고 FETCH NEXT 에서 몇 개의 행을 가져올 지 결정하게 됩니다.
<?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
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);
}
}