본문 바로가기
Spring

[SpringBoot/IntelliJ] Spring Data JPA 페이징

by noddu 2022. 4. 18.
728x90
반응형

 

public interface SpringDataJpaRepository extends JpaRepository<MainBoard, Long> {
}

Jparepository를 상속하는 respository가 있다

 


@GetMapping("/mainProductBoard")
public String list(Model model){
    List<MainBoard> mainBoardList = springDataJpaRepository.findAll();
    model.addAttribute("mainproducts",mainBoardList);
    return "boards/board";
}

기존의 findAll()로 모든 list를 가져와서

 

 

<div> 총 건수 : <span th:text="${#lists.size(mainproducts)}"></span></div>

받아온 mainproducts의 size를 출력해보면

 

 

 

14개가 나온다

 


 

 

https://docs.spring.io/spring-data/jpa/docs/current/reference/html/

 

Spring Data JPA - Reference Documentation

Example 109. Using @Transactional at query methods @Transactional(readOnly = true) interface UserRepository extends JpaRepository { List findByLastname(String lastname); @Modifying @Transactional @Query("delete from User u where u.active = false") void del

docs.spring.io

 

Documentation에서 Reference Doc.을 클릭하면

 

이렇게 페이징 예제가 있다

 

 


@GetMapping("/mainProductBoard")
public String list(Model model){
    Page<MainBoard> mainBoardList = springDataJpaRepository.findAll(PageRequest.of(0,20));
    model.addAttribute("mainproducts",mainBoardList);
    return "boards/board";
}

위의 샘플코드처럼 바꿔봤다

Jpa에서는 기본적으로 첫번째 페이지가 0부터 시작이라서 0으로 설정했다

 

실행했더니 총 건수가 1로 바뀐걸 볼 수 있다

 


 

Debug모드로 확인해보니 총 14건이 잘나오고

page는 0번, size는 20으로 잘 출력된다

sort(정렬)은 아직 설정하지 않았다


getPageable() - 페이지 정보

 

 

getTotalPages() - 총 페이지 수

 

 

getTotalElements() - 전체 데이터 수

 


<div> 총 건수 : <span th:text="${mainproducts.totalElements}"></span></div>

아까 사용했던 html에서 getTotalElements를 사용할건데

thymeleaf에서는 메소드를 적지않고 다음과 같이 사용한다 

 

 

그러면 다시 14건이 잘 출력된다

 


@GetMapping("/mainProductBoard")
public String list(Model model, Pageable pageable){
    Page<MainBoard> mainBoardList = springDataJpaRepository.findAll(pageable);
    model.addAttribute("mainproducts",mainBoardList);
    return "boards/board";
}

Controller 코드를 findAll(Pageable)로 바꾼다

 

 

page와 size등 파라미터 전달이 가능해진다

 


 

@GetMapping("/mainProductBoard")
public String list(Model model, Pageable pageable){
    Page<MainBoard> mainBoardList = springDataJpaRepository.findAll(pageable);
    int startPage = Math.max(0,mainBoardList.getPageable().getPageNumber() -4);   // getPageNumber() - 현재 페이지
    int endPage = Math.min(mainBoardList.getTotalPages(), mainBoardList.getPageable().getPageNumber() + 4);
    model.addAttribute("startPage",startPage);
    model.addAttribute("endPage",endPage);

    model.addAttribute("mainproducts",mainBoardList);
    return "boards/board";
}

Controller에서 list의 TotalPage와 getPageable.getNumber를 사용해서

startPage와 endPage를 넘긴다

Math.min, max로 최소,최댓값을 정했다


https://getbootstrap.com/docs/5.1/components/pagination/#overview

 

Pagination

Documentation and examples for showing pagination to indicate a series of related content exists across multiple pages.

getbootstrap.com

 

 

Pagination

Documentation and examples for showing pagination to indicate a series of related content exists across multiple pages.

getbootstrap.com

<nav aria-label="Page navigation example">
    <ul class="pagination justify-content-center">
        <li class="page-item disabled">
            <a class="page-link">Previous</a>
        </li>
        <li class="page-item"><a class="page-link" href="#">1</a></li>
        <li class="page-item"><a class="page-link" href="#">2</a></li>
        <li class="page-item"><a class="page-link" href="#">3</a></li>
        <li class="page-item">
            <a class="page-link" href="#">Next</a>
        </li>
    </ul>
</nav>

부트스트랩에서 가져온 복사한 코드를 복사한다음

 

 

<li class="page-item" th:each="i : ${#numbers.sequence(startPage,endPage)}">
    <a class="page-link" href="#" th:text="${i}">1</a>
</li>

page-item을 roop문으로 돌려주고

값을 i로하면된다

( 위에 controller 코드에서 Math.max(1, ...)해야 1번부터 시작한다 )

 

 

잘 나온다 ( size파라미터값을 빼면 페이징 1밖에 안나온다 )

 


@GetMapping("/mainProductBoard")
public String list(Model model, @PageableDefault(size=3) Pageable pageable){

파라미터(size)를 직접 치지않게 PageableDefault 어노테이션을 작성해 size값을 선언한다

 

그럼 size만큼 데이터 갯수가 출력된다

 


<li class="page-item" th:classappend="${i == mainproducts.pageable.pageNumber + 1} ? 'disabled'" th:each="i : ${#numbers.sequence(startPage,endPage)}">

숫자 클릭 부분은 만약 i (1부터시작) 가 현재페이지(0부터시작)+1 와 같다면 disabled를 줘서 클릭을 못하게한다

 

 

<li class="page-item" th:classappend="${1 == mainproducts.pageable.pageNumber + 1} ? 'disabled'">
    <a class="page-link">Previous</a>
</li>
<li class="page-item" th:classappend="${i == mainproducts.pageable.pageNumber + 1} ? 'disabled'" th:each="i : ${#numbers.sequence(startPage,endPage)}">
    <a class="page-link" href="#" th:text="${i}">1</a>
</li>
<li class="page-item" th:classappend="${mainproducts.totalPages == mainproducts.pageable.pageNumber + 1} ? 'disabled'">
    <a class="page-link" href="#">Next</a>
</li>

Previous 버튼과 Next에도 조건을 줘서 disabled를 준다

 


<li class="page-item" th:classappend="${1 == mainproducts.pageable.pageNumber + 1} ? 'disabled'">
    <a class="page-link" th:href="@{/mainProductBoard(page = ${mainproducts.pageable.pageNumber -1})}">Previous</a>
</li>
<li class="page-item" th:classappend="${i == mainproducts.pageable.pageNumber + 1} ? 'disabled'" th:each="i : ${#numbers.sequence(startPage,endPage)}">
    <a class="page-link" th:href="@{/mainProductBoard(page = ${i -1})}" th:text="${i}">1</a>
</li>
<li class="page-item" th:classappend="${mainproducts.totalPages == mainproducts.pageable.pageNumber + 1} ? 'disabled'">
    <a class="page-link" th:href="@{/mainProductBoard(page = ${mainproducts.pageable.pageNumber +1})}">Next</a>
</li>

이제 Previous와 숫자, Next버튼을 눌렀을때 파라미터값을 위 코드처럼 넘긴다

숫자 클릭 부분은 page의 넘버가 아니라 인덱스의 번호를 파라미터로 가져야해서 -1해준다

 

잘 실행된다!!

반응형