이전글
https://greed-yb.tistory.com/209
DataTables 는 자체적으로 페이징 처리를 해주고
Thymeleaf 방식으로 페이징 처리는 이전글에서 다뤄보았다.
Pageable 을 다뤄보기 전에 정리 한번 해보려 한다.
Controller
@Controller
public class WebController {
@Autowired
private PageTestService pageTestService;
// 페이징 테스트 게시판
@GetMapping("/pageTest")
public String pageTest() throws Exception{
return "pageTest";
}
// 페이징 테스트 게시판 목록 불러오기
@GetMapping("/pageTestList")
@ResponseBody
public PageMaker<PageTestVo> pageTestList(SearchMaker searchMaker) throws Exception{
return pageTestService.select(searchMaker);
}
}
service
public interface PageTestService {
// 게시글 조회
PageMaker<PageTestVo> select(SearchMaker searchMaker) throws Exception;
}
serviceImpl
@Service
public class PageTestServiceImpl implements PageTestService {
@Autowired
private PageTestMapper testMapper;
@Override
public PageMaker<PageTestVo> select(SearchMaker searchMaker) throws Exception {
// 글의 총 개수
int total = testMapper.total(searchMaker);
// 글 검색
List<PageTestVo> vo = testMapper.select(searchMaker);
return new PageMaker<>(searchMaker, total, vo);
}
}
mapper.class
@Mapper
public interface PageTestMapper {
List<PageTestVo> select(SearchMaker searchMaker) throws Exception;
int total(SearchMaker searchMaker) throws Exception;
}
mapper.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="com.example.practice.mapper.pageTest.PageTestMapper">
<select id="select" resultType="com.example.practice.vo.pageTest.PageTestVo">
SELECT *
FROM (SELECT ROW_NUMBER() OVER(ORDER BY NO DESC) AS NUM,
NO,
CONTENT
FROM PAGETEST
<if test="searchKeyWord != null">
WHERE CONTENT LIKE '%' || #{searchKeyWord} || '%'
</if>
)
WHERE NUM BETWEEN #{rowStart} AND #{rowEnd}
</select>
<select id="total" resultType="int">
SELECT COUNT(NO) FROM PAGETEST
<if test="searchKeyWord != null">
WHERE CONTENT LIKE '%' || #{searchKeyWord} || '%'
</if>
</select>
</mapper>
DB 는 Oracle 을 사용했다.
DB 에 맞춰서 시작(rowStart)과 끝(rowEnd)을 설정해야한다.
vo
public class PageTestVo {
String no;
String content;
-- getter , setter 구현부 --
}
SearchMaker - 검색 페이징
public class SearchMaker {
private int page; // 현재 페이지
private int size; // 페이지 당 글의 게시물 개수
private String searchKeyWord; // 검색 키워드
private String type; // 검색 조건
// Mapper 에서 가져올 데이터 시작과 끝
private int rowStart;
private int rowEnd;
// 기본 값
public SearchMaker(){
this.page = 1;
this.size = 10;
}
public int getPage() {
return page;
}
public void setPage(int page) {
this.page = page;
}
public int getSize() {
return size;
}
public void setSize(int size) {
this.size = size;
}
public String getSearchKeyWord() {
return searchKeyWord;
}
public void setSearchKeyWord(String searchKeyWord) {
this.searchKeyWord = searchKeyWord;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
// 쿼리에서 가져올 데이터 위치
public int getRowStart() {
return ((this.page - 1) * this.size) + 1;
}
public void setRowStart(int rowStart) {
this.rowStart = rowStart;
}
// 쿼리에서 가져올 데이터 위치
public int getRowEnd() {
return (getRowStart() + this.size) - 1;
}
public void setRowEnd(int rowEnd) {
this.rowEnd = rowEnd;
}
}
PageMaker - 페이지 바
public class PageMaker<T> {
private int totalPage; // 페이지 총 개수
private int size; // 페이지 당 글 개수
private int currentPage; // 현재 페이지
private int startPage; // 시작 페이지
private int endPage; // 끝 페이지
private boolean prev; // 이전 페이지
private boolean next; // 다음 페이지
private List<T> result; // 검색 데이터
public PageMaker(SearchMaker searchMaker, int totalCount, List<T> vo){
this.size = searchMaker.getSize(); // 페이지 당 글 개수
this.currentPage = searchMaker.getPage(); // 현재 페이지
// 총 페이지 수
this.totalPage = (int) Math.ceil((double) totalCount / size);
// 페이지 버튼 bar
this.endPage = (int) ((Math.ceil(this.currentPage / 10.0)) * 10); // 페이지 10개씩 보여짐
this.startPage = this.endPage - 9; // 페이지 10개씩 보여짐
// this.endPage = (int) ((Math.ceil(this.currentPage / 5.0)) * 5); // 페이지 5개씩 보여짐
// this.startPage = this.endPage - 5; // 페이지 5개씩 보여짐
if(this.endPage > this.totalPage){
this.endPage = this.totalPage;
}
this.prev = this.startPage > 1;
this.next = this.totalPage > this.endPage;
this.result = vo; // 조회 한 게시글 데이터
}
-- getter , setter 구현부--
}
html
<div class="card shadow mb-4">
<div class="card-header py-3" style="text-align: right">
<!-- <button class="btn btn-secondary" id="writeBtn" type="button" onclick="writePageBtn()">글쓰기</button>-->
</div>
<div class="card-body">
<div class="table-responsive">
<select class="form-select" id="searchSize">
<option value="10">10개</option>
<option value="30">30개</option>
<option value="50">50개</option>
</select>
<div class="row">
<div class="col-sm-6 mb-3 mb-sm-0">
<input type="text" class="form-control form-control-user" id="searchKeyWord" placeholder="제목">
</div>
<button class="btn btn-primary" type="button" id="pageTestBtn" onclick="searchBtn()">검색</button>
</div>
<table class="table table-bordered" id="board_dataTable" style="width: 98%">
<thead>
<tr>
<th>No</th>
<th>제목</th>
</tr>
</thead>
<tbody>
<!-- 글 목록 -->
</tbody>
</table>
<!-- css 미적용 -->
<div id="pagingBar"></div>
<!-- bootstrap css -->
<!--<div id="pagingBar">-->
<!-- <ul class="pagination justify-content-center" id="pagingUl"></ul>-->
<!--</div>-->
</div>
</div>
</div>
<script th:src="@{/bootstrap/js/pageTest.js}"></script>
javascript
// 페이지 기본값
let page = 1;
let size;
let searchKeyWord;
/**
* 보여지는 글 개수 변경 시
*/
$("#searchSize").change(function (){
page = 1;
size = $("#searchSize").val();
searchKeyWord = $("#searchKeyWord").val();
search();
})
/**
* BootStrap 페이지 바 생성
*/
// function pageBar(data){
// if (data.prev) {
// $('#pagingUl').append(`<li class="page-item"><a href="#" class="page-link" data-page="1">처음</a></li>`);
// $('#pagingUl').append(`<li class="page-item"><a href="#" class="page-link" data-page="${data.startPage - 1}">이전</a></li>`);
// }
//
// for (let i = data.startPage; i <= data.endPage; i++) {
//
// let active = (i === data.currentPage) ? 'active' : '';
//
// $('#pagingUl').append(`<li class="page-item ${active}"><a href="#" class="page-link" id="pageNum_${i}" data-page="${i}">${i}</a></li>`);
// }
//
// if (data.next) {
// $('#pagingUl').append(`<li class="page-item"><a href="#" class="page-link" data-page="${data.endPage + 1}">다음</a></li>`);
// $('#pagingUl').append(`<li class="page-item"><a href="#" class="page-link" data-page="${data.totalPage}">끝</a></li>`);
// }
// }
/**
* 기본 페이지 바 생성
*/
function pageBar(data){
if (data.prev) {
$('#pagingBar').append(`<a href="#" data-page="1">처음</a>`);
$('#pagingBar').append(`<a href="#" data-page="${data.startPage - 1}">이전</a>`);
}
for (let i = data.startPage; i <= data.endPage; i++) {
$('#pagingBar').append(`<a href="#" id="pageNum_${i}" data-page="${i}">${i}</a>`);
}
if (data.next) {
$('#pagingBar').append(`<a href="#" data-page="${data.endPage + 1}">다음</a>`);
$('#pagingBar').append(`<a href="#" data-page="${data.totalPage}">끝</a>`);
}
// 클릭한 페이지 번호에 css 색 넣기
$("#" + "pageNum_"+page).css("color", "red")
}
/**
* 페이지 이동
*/
$("#pagingBar").on("click", "a", function (){
page = $(this).data("page");
search();
})
/**
* 검색 버튼
*/
function searchBtn(){
page = 1;
search();
}
/**
* 검색
*/
function search(){
size = $("#searchSize").val();
searchKeyWord = $("#searchKeyWord").val();
$.ajax({
url : "/pageTestList",
method : "GET",
data : { "page": page, "size" : size , "searchKeyWord" : searchKeyWord},
success : function (data){
// 목록 초기화
$("#board_dataTable tbody").empty();
// 페이지 바 초기화
$('#pagingBar').empty(); // css 미적용
// $('#pagingUl').empty(); // bootstrap css 적용
if(data.result != "" ){
for (let i = 0; i < data.result.length; i++) {
$("#board_dataTable").append('<tr><td>'+ data.result[i].no +'</td><td>'+ data.result[i].content +'</td></tr>');
}
pageBar(data);
}else{
$("#board_dataTable").append('<tr><td colspan="2">데이터가 없습니다.</td></tr>');
}
}
})
}
$(document).ready(function (){
// 검색
search();
});
TEST
BootStrap CSS 가 필요하다면 주석만 반대로 적용해 주면 된다.
TEST 를 위한 DB 테이블과 VO 를 생성했기 때문에
본인의 DB에 맞춰서 변경할 것
'개발 > Spring' 카테고리의 다른 글
[SpringBoot] Intellij + React 생성 및 한번에 빌드하기 (0) | 2024.10.21 |
---|---|
[Mybatis + Pageable] 게시판 페이징 처리 (0) | 2024.10.18 |
[Spring MVC] IntelliJ 에서 프로젝트 생성(4) - Tomcat 연결 (3) | 2024.10.04 |
[Spring MVC] IntelliJ 에서 프로젝트 생성(3) - 폴더 구조 (0) | 2024.10.04 |
[Spring MVC] IntelliJ 에서 프로젝트 생성(2) - 설정 (0) | 2024.10.04 |
댓글