항상 오라클만 썻던 나에게는
오라클 처럼 rownum으로 하면 되겠지??
라고 생각하던 차에 새로 만들고 있는 웹사이트에서 행복 회로를 돌리며
매퍼작성을 끝냇는데
응 ?? badsql?? 읭 왜??
나의 착오 였다.
그렇다
MYSQL에서는 ROWNUM을 지원하지 않아
다른 문법으로 해야한다.
그래서 폭풍 검색끝에 limit이라는 걸 찾아 냈다.
오히려 오라클보다 너무 쉬워 까먹기전에 포스팅을 해야겠다고 생각했다.
우선 구현한 페이지를 보자
우선 페이지삼아 더미데이터를 약 2만 7천개 정도 넣었다 .
10만개가 안되면 데이터테이블쓰는게 이롭지만..
각설 하고 기존 오라클 페이징 에서 크게 벗어나지는 않는다.
우선 모델 객체부터 살펴보자 .
PageVO 객체
@Getter
@Setter
@ToString
public class PageVO {
//사용자가 선택한 페이지 정보를 담을 변수.
private int pageNum;
private int countPerPage;
//검색에 필요한 데이터를 변수로 선언.
private String keyword;
private String condition;
public PageVO() {
this.pageNum = 1;
this.countPerPage = 10;
}
}
앞서 설명한거와 같이 사용자가 선택한 페이지 정보를 담고
검색은 키워드와 컨디션으로 통일한다.
그리고 생성자를 하나 꺼내 맨 처음 페이지 1과 페이지에 보여줄 게시글 수 10개를 선택해준다.
PageCreate 객체
@Getter
@Setter
@ToString
public class PageCreate {
private PageVO paging;
private int articleTotalCount;
private int endPage;
private int beginPage;
private boolean prev;
private boolean next;
private final int buttonNum = 5;
private void calcDataOfPage() {
endPage = (int) (Math.ceil(paging.getPageNum() / (double) buttonNum) * buttonNum);
beginPage = (endPage - buttonNum) + 1;
prev = (beginPage == 1) ? false : true;
next = articleTotalCount <= (endPage * paging.getCountPerPage()) ? false : true;
if(!next) {
endPage = (int) Math.ceil(articleTotalCount / (double) paging.getCountPerPage());
}
}
public void setArticleTotalCount(int articleTotalCount) {
this.articleTotalCount = articleTotalCount;
calcDataOfPage();
}
그 후 endpage next 등 페이지를 설정 해준다.
여기서 setArticleTotalCount는
컨트롤러에서 총 게시물의 개수를 PageCreate에게 전달한 직후에
바로 페이징 버튼 알고리즘이 들어수 있도록 setter를 약간의 커스텀을 해줆.
그 후 검색을 할수 있게 아래와 같이 sql문을 매퍼에 작성해준다.
1. 특정 문자로 시작하는 데이터 검색
SELECT [필드명] FROM [테이블명] WHERE [필드명] LIKE '특정 문자열%';
2. 특정 문자로 끝나는 데이터 검색
SELECT [필드명] FROM [테이블명] WHERE [필드명] LIKE '%특정 문자열';
3. 특정 문자를 포함하는 데이터 검색
SELECT [필드명] FROM [테이블명] WHERE [필드명] LIKE '%특정 문자열%';
[MySQL]
title like CONCAT('%',#{keyword},'%')
[Oracle]
title like '%' || #{keyword} || '%'
[MSSQL]
title like '%' + #{keyword} + '%'
로 지정해주면 된다.
<sql id="search">
<if test="condition == 'freeboard_title'">
WHERE freeboard_title LIKE CONCAT('%',#{keyword},'%')
</if>
<if test="condition == 'freeboard_content'">
WHERE freeboard_content LIKE CONCAT('%',#{keyword},'%')
</if>
<if test="condition == 'freeboard_writer'">
WHERE freeboard_writer LIKE CONCAT('%',#{keyword},'%')
</if>
</sql>
<!-- 토탈 -->
<select id="getTotal" resultType="int">
SELECT COUNT(*)
FROM Vegan_freeBoard
<include refid="search" />
</select>
<select id="getFreeBoard" resultType="com.vegan.recipe.freeBoard.freeboardVO">
select * from Vegan_freeBoard
<include refid="search" />
order by freeboard_no desc
limit #{pageNum} , #{countPerPage}
</select>
토탈을 구해주고 리밋으로 페이지넘과 페이지 수를 전달해준다.
컨트롤러 부분
@GetMapping("/freeList")
public String getFree(Model model, PageVO vo) {
PageCreate pc = new PageCreate();
pc.setPaging(vo);
pc.setArticleTotalCount(service.getTotal(vo));
System.out.println(pc);
model.addAttribute("freeList", service.getFreeBoard(vo));
model.addAttribute("pc", pc);
return "FreeBoard/freeList";
}
페이지 크리에이트 와 pagevo 객체를 변수 로 선택해주고 모델로 뷰로 날려준다.
</div>
<form action="<c:url value='/FreeBoard/freeList'/>">
<div class="search-wrap clearfix">
<button type="submit" class="btn btn-primary search-btn" style="margin-right: 24%;">검색</button>
<input type="text" name="keyword" class="form-control search-input" value="${pc.paging.keyword}"
style="width: 200px; ">
<select class="form-control" id="search-select" name="condition" style="width: 80px; margin-left: 54%">
<option value="freeboard_title" ${pc.paging.condition == 'freeboard_title' ? 'selected' : ''}>제목</option>
<option value="freeboard_content" ${pc.paging.condition == 'freeboard_content' ? 'selected' : ''}>내용</option>
<option value="freeboard_writer" ${pc.paging.condition == 'freeboard_writer' ? 'selected' : ''}>작성자</option>
</select>
</div>
</form>
<!-- 비건 뉴스 상세보기 -->
<table class="table" style="width: 70%; margin: 0 auto;">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">제목</th>
<th scope="col">작성자</th>
<th scope="col">작성 시간</th>
<th scope="col">조회수</th>
<th scope="col">좋아요</th>
</tr>
</thead>
<tbody>
<c:forEach var="vo" items="${freeList}">
<tr>
<th scope="row">${vo.freeboard_no}</th>
<td><a href="<c:url value='/FreeBoard/freeDetail?freeboard_no=${vo.freeboard_no}'/>">${vo.freeboard_title}</a></td>
<td>${vo.freeboard_writer}</td>
<td>${vo.freeboard_regDate}</td>
<td>${vo.freeboard_hit}</td>
<td>${vo.freeboard_like}</td>
</tr>
</c:forEach>
</tbody>
</table>
<!-- 글작성 -->
<div class="newsWrite">
<button type="button" class="btn btn-primary whyBtn">글작성</button>
</div>
<!-- 페이징 -->
<div class="paging">
<form action="<c:url value='/FreeBoard/freeList' />" name="pageForm">
<div class="text-center clearfix">
<ul class="pagination" id="pagination">
<c:if test="${pc.prev}">
<li class="page-item "><a class="page-link" href="#" data-pageNum="${pc.beginPage-1}">Prev</a></li>
</c:if>
<c:forEach var="num" begin="${pc.beginPage}" end="${pc.endPage}">
<li class="${pc.paging.pageNum == num ? 'age-item active' : ''}" page-item><a class="page-link" href="#" data-pageNum="${num}">${num}</a></li>
</c:forEach>
<c:if test="${pc.next}">
<li class="page-item"><a class="page-link" href="#" data-pageNum="${pc.endPage+1}">Next</a></li>
</c:if>
</ul>
<!-- 페이지 관련 버튼을 클릭 시 같이 숨겨서 보낼 값 -->
<input type="hidden" name="pageNum" value="${pc.paging.pageNum}">
<input type="hidden" name="countPerPage" value="${pc.paging.countPerPage}">
<input type="hidden" name="keyword" value="${pc.paging.keyword}">
<input type="hidden" name="condition" value="${pc.paging.condition}">
</div>
</form>
</div>
<%@include file="../include/footer.jsp"%>
</body>
<script>
$(function() {
$('.whyBtn').click(function() {
location.href = '<c:url value="/FreeBoard/freeWrite"/>';
})
$('#pagination').on('click', 'a', function(e) {
e.preventDefault();
console.log($(this));
const value = $(this).data('pagenum');
console.log(value);
document.pageForm.pageNum.value = value;
document.pageForm.submit();
});
})
</script>
</html>
그 후 검색으로 올 수 있도록 select로 option값을 준다. 그 뒤 컨트롤러로 보내 sql문을 타게해 조회된 결과를 보여주면 된다.
페이징 같은 경우는 hidden으로 값을 숨겨 보낸뒤 자바스크립트로 마무리를 해주었다.
작동이 아주 잘된다.
'Spring > 비건레시피사이트' 카테고리의 다른 글
스프링 좋아요 구현 및 게시판 리스트에 댓글 수 표시(ajax,마이바티스) (0) | 2022.04.21 |
---|---|
CK에디터4 이미지업로드 (스프링) 디비필요없음! (9) | 2022.04.14 |
mysql 페이징 삽질 후기.. (0) | 2022.04.12 |
스프링 MYSQL 연동 방법 (마이바티스) (0) | 2022.04.08 |
비건레시피사이트 메인페이지 제작 (2) | 2022.04.05 |