본문 바로가기

Project

[LogicList]Spring 타임리프 환경 페이징 구현

반응형

백엔드 구현 필요사항 

  1. 페이지 관련 도메인 클래스 생성
  2. Controller 클래스에서 Page 파라미터 받기
  3. 관련 키워드에 대한 총 게시글 수 쿼리문 작성

프론트 구현 필요사항

  1. 현재페이지 구분
  2. 페이지 도메인 클래스 출력

1. 페이지 관련 도메인 클래스 생성

package swlee.logiclist.domain;

import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class PageMaker {

    private int totalCount; // 게시글 총 갯수
    private int startPage; // 현재 페이지
    private int endPage; // 마지막 페이지
    private int totalPage;// 전체 페이지
    private boolean next; // 페이지 다음 버튼 (사용안함)
//    private int displayPageNum = 5;


    public void setTotalCount(int totalCount) {
        // BoardRepository 에서 총 Count를 받아온다.
        this.totalCount = totalCount; //12
        //페이지 관련 데이터 처리
        calcData();
    }

    public void setStartPage(int startPage){
        //Controller 에서 page 값을 받아와 저장
        this.startPage=startPage;
        // 총 10개의 페이지를 보여줌
        setEndPage(startPage+9);

    }
    //현재 사용안함
    public boolean isNext() {
        return next;
    }

    private void calcData() { // 페이지 데이터 처리
        // totalCount%10==0 일시 총 페이지갯수가 10으로 나누어 떨어짐
        if(this.totalCount%10==0){
            this.totalPage=(int)(Math.ceil(this.totalCount/10.0));

        }
        // 맞아 떨이지지 않는다면 +1 하여 나머지 게시글도 출력필요
        else{
            this.totalPage=(int)(Math.ceil(this.totalCount/10.0))+1;
        }
        // totalPage(총 게시글 갯수를 page 단위로 나눈 값)가 endPage보다 크면 Next 버튼 생성
        if(totalPage>endPage){
            //사용안함
            setNext(true);
        }
        else{
            // totalPage가 endPage보다 작으면 Next 버튼 생성하지 않으며, endPage를 totalPage로 변경
            setEndPage(totalPage);
            setNext(false);
        }
    }



}

2. Controller 클래스에서 Page 파라미터 받기

@GetMapping("/list")
public String list(@RequestParam(value="keyword")@NonNull String keyword, @RequestParam(value="page",defaultValue ="1")String pages, Model model, Principal principal, HttpServletRequest request, HttpServletResponse response) throws IOException {
    PageMaker pageMaker = new PageMaker();
    pageMaker.setStartPage(Integer.parseInt(pages));
    //총 게시글 갯수 가져오기
    int total = boardService.count(keyword);
    pageMaker.setTotalCount(total);
    // 비정상 접근 핸들링
    if(keyword.isBlank()||keyword.isEmpty()||keyword==null){
        ScriptUtils.alertAndBackPage(response,"비정상적인 접근입니다.");
    }
    List<Board> boards = boardService.findByName(keyword,pages);
    if(boards.isEmpty()){
        ScriptUtils.alertAndBackPage(response,"검색결과가 없습니다.");

    }
    model.addAttribute("boards",boards);
    model.addAttribute("pageMaker",pageMaker);

    return "board/list";
}

3. 관련 키워드에 대한 총 게시글 수 쿼리문 작성

BoardService

@Override
public int count(String keyword){
    return boardRepository.count(keyword);
}

BoardRepository

@Override
public int count(String keyword){
    final String sql = "SELECT count(*) FROM board WHERE title LIKE ?";
    int count = jdbcTemplate.queryForObject(sql, Integer.class, "%"+keyword+"%");
    log.info("title :{} count : {}",keyword,count);
    return count;
}

 

키워드 관련 검색 시 현재 페이지(컨트롤러에서 전달받은 page 파라미터)로 가져올 데이터를 10개씩 전달받음

(DataBase - Postgresql 사용으로 쿼리문이 다를 수 있음)

 @Override
    public List<Board> findByName(String keyword,String pages) {
        int page = Integer.parseInt(pages);
        int start = (page-1)*10;
        log.info("start : "+start);
        //postgres
        final String sql = "SELECT * FROM board WHERE title LIKE ? ORDER BY created_at ASC LIMIT 10 OFFSET ?";

        List<Board> findBoard = jdbcTemplate.query(sql, getRowMapper(), "%"+keyword+"%",start);
        log.info("findBoard : {}",findBoard);
        return findBoard;

    }

프론트 구현 필요사항

  <div class="e38_105">
    <nav style="text-align: center;">
        <ul class="pagination" th:with="start=${pageMaker.startPage}, end=${pageMaker.endPage}">

            <li th:each="page: ${#numbers.sequence(start, end)}">
                <th:block th:if="${pageStat.first}">
                    <a class="active" th:href="@{list(page=${page},keyword=${#httpServletRequest.getParameter('keyword')})}" th:text="${page}"></a>
                </th:block>
                <th:block th:if="${!pageStat.first}">
                    <a th:href="@{list(page=${page},keyword=${#httpServletRequest.getParameter('keyword')})}" th:text="${page}"></a>
                </th:block>
            </li>


        </ul>
    </nav>


</div>

제일 처음 페이지일 경우 active 클래스 추가 

<th:block th:if="${pageStat.first}">
    <a class="active" th:href="@{list(page=${page},keyword=${#httpServletRequest.getParameter('keyword')})}" th:text="${page}"></a>
</th:block>

결과


개선 필요사항

  1. 다음, 이전 버튼 필요
  2. 현재 접속 페이지가 맨처음 페이지로 옴
반응형