[Spring Boot] Easy paging recipe

environment

Language: java 1.8 Framework: spring boot 2.2.4.RELEASE (spring-boot-starter) Template engine: thymeleaf 2.2.4.RELEASE (spring-boot-starter) Database: H2 1.4.200 (spring-boot-starter) orm : data-jpa 2.2.4.RELEASE (spring-boot-starter)

Source code

Entity

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

@Entity
public class Board {

	@Id @GeneratedValue
	private String id;
	
	private String title;
	
	private String user; 
	
    //Getter / Setter omitted
    
}

Pagination

public class Pagination {

	/** 1.Number of bulletins to be displayed on the page**/
	private int pageSize = 10;

	/** 2.Number of paging blocks**/
	private int blockSize = 10;

	/** 3.Current page**/
	private int page = 1;

	/** 4.Currently blocked**/
	private int block = 1;

	/** 5.Total number of bulletins**/
	private int totalListCnt;

	/** 6.Total number of pages**/
	private int totalPageCnt;

	/** 7.Total number of blocks**/
	private int totalBlockCnt;

	/** 8.Block start page**/
	private int startPage = 1;

	/** 9.Last page of block**/
	private int endPage = 1;

	/** 10.DB approach start index**/
	private int startIndex = 0;

	/** 11.Last page of previous block**/
	private int prevBlock;

	/** 12.Last page of next block**/
	private int nextBlock;
    
    //Getter / Setter omitted

	public Pagination(int totalListCnt, int page) {

		//Get the total number of posts and the current page from the controller.
		//Total number of bulletins- totalListCnt
		//Current page- page
		
		/** 3.Current page**/
		setPage(page);
		
		/** 5.Total number of bulletins**/
		setTotalListCnt(totalListCnt);

		/** 6.Total number of pages**/
		setTotalPageCnt((int) Math.ceil(totalListCnt * 1.0 / pageSize));

		/** 7.Total number of blocks**/
		setTotalBlockCnt((int) Math.ceil(totalPageCnt * 1.0 / blockSize));
		
		/** 4.Currently blocked**/
		setBlock((int) Math.ceil((page * 1.0)/blockSize)); 

		/** 8.Block start page**/
		setStartPage((block - 1) * blockSize + 1);
		
		/** 9.Last page of block**/
		setEndPage(startPage + blockSize - 1);
        
		/* ===Variations on the last black page===*/
		if(endPage > totalPageCnt){this.endPage = totalPageCnt;}
		
		/** 11.Last page of previous block**/
		setPrevBlock((block * blockSize) - blockSize);

		/* ===Variations on previous blocks=== */
		if(prevBlock < 1) {this.prevBlock = 1;}

		/** 12.Last page of next block**/
		setNextBlock((block * blockSize) + 1);
		
		/* ===Variations on the next block===*/
		if(nextBlock > totalPageCnt) {nextBlock = totalPageCnt;}
        
		/** 10.DB approach start index**/
		setStartIndex((page-1) * pageSize);
	
	}
}

Controller

@GetMapping("/")
public String home(Model model, @RequestParam(defaultValue = "1") int page) {

    //Total number of bulletins
    int totalListCnt = boardRepository.findAllCnt();

    //Total number of posts and current page
    Pagination pagination = new Pagination(totalListCnt, page);

    //DB approach start index
    int startIndex = pagination.getStartIndex();
    
    //Maximum number of bulletins to display on a page
    int pageSize = pagination.getPageSize();

	//Bulletin acquisition
    List<Board> boardList = boardRepository.findListPaging(startIndex, pageSize);

	//Object storage in model object
    model.addAttribute("boardList", boardList);
    model.addAttribute("pagination", pagination);

    return "index";
}

Repository

@Repository
public class BoardRepository {

	@PersistenceContext
	private EntityManager em;

	public int findAllCnt() {
		return ((Number) em.createQuery("select count(*) from Board")
					.getSingleResult()).intValue();
	}

	public List<Board> findListPaging(int startIndex, int pageSize) {
		return em.createQuery("select b from Board b", Board.class)
					.setFirstResult(startIndex)
					.setMaxResults(pageSize)
					.getResultList();
	}
}

html

<!DOCTYPE html>
<html 	lang="ja" 
        xmlns="http://www.w3.org/1999/xhtml" 
        xmlns:th="http://www.thymeleaf.org">
			
<head>
	<meta charset="UTF-8">
	<title>paging</title>
		<link rel="stylesheet" th:href="@{/css/bootstrap.min.css}">
	</head>
<body>
 
<table class="table table-striped">

  <thead class="thead-dark">
    <tr>
      <th scope="col" style="width: 10%">no</th>
      <th scope="col">title</th>
      <th scope="col" style="width: 15%">user</th>
    </tr>
  </thead>
  
  <tbody>
    <tr th:each="board : ${boardList}">
      <th scope="row" th:text="${boardStat.index + 1}">1</th>
      <td th:text="${board.title}"></td>
      <td th:text="${board.user}"></td>
    </tr>
  </tbody>
  
</table>

//paging
<nav aria-label="Page navigation example ">
  <ul class="pagination">
  <li class="page-item">
      <a class="page-link" th:href="@{/?page=1}" aria-label="Previous">
        <span aria-hidden="true"><<</span>
      </a>
    </li>
    <li class="page-item">
      <a class="page-link" th:href="@{/?page={page} (page = ${pagination.prevBlock})}" aria-label="Previous">
        <span aria-hidden="true"><</span>
      </a>
    </li>
    <th:block  th:with="start = ${pagination.startPage}, end = ${pagination.endPage}">
	    <li class="page-item" 
	    		 th:with="start = ${pagination.startPage}, end = ${pagination.endPage}"
	    		th:each="pageButton : ${#numbers.sequence(start, end)}">
	    		<a class="page-link" th:href="@{/?page={page} (page = ${pageButton})}" th:text=${pageButton}></a>
	    </li>
    </th:block>
    <li class="page-item">
      <a class="page-link" th:href="@{?page={page} (page = ${pagination.nextBlock})}" aria-label="Next">
        <span aria-hidden="true">></span>
      </a>
    </li>
    <li class="page-item">
      <a class="page-link" th:href="@{?page={page} (page = ${pagination.totalPageCnt})}" aria-label="Previous">
        <span aria-hidden="true">>></span>
      </a>
    </li>
  </ul>
</nav>

</body>
</html>

Remarks

Recommended Posts

[Spring Boot] Easy paging recipe
Challenge Spring Boot
Spring Boot Form
Implement paging function with Spring Boot + Thymeleaf
Spring Boot Memorandum
gae + spring boot
SPRING BOOT learning record 01
Spring Boot + Heroku Postgres
First Spring Boot (DI)
SPRING BOOT learning record 02
Spring Boot2 cheat sheet
Spring Boot exception handling
Spring Boot Servlet mapping
Spring boot development-development environment-
Spring Boot learning procedure
Learning Spring Boot [Beginning]
Spring boot memo writing (2)
Spring Boot 2.2 Document Summary
[Spring Boot] DataSourceProperties $ DataSourceBeanCreationException
Spring Boot 2.3 Application Availability
Spring boot tutorials Topics
Download with Spring Boot
[Spring Boot] Environment construction (macOS)
Set context-param in Spring Boot
Try Spring Boot from 0 to 100.
Generate barcode with Spring Boot
Hello World with Spring Boot
Spring Boot on Microsoft Azure
Implement GraphQL with Spring Boot
Spring Boot tutorial task schedule
Spring 5 & Spring Boot 2 Hands-on preparation procedure
Hello World with Spring Boot!
Spring Boot 2 multi-project in Gradle
[Spring Boot] Web application creation
spring boot port duplication problem
Run LIFF with Spring Boot
SNS login with Spring Boot
Spring Boot Hot Swapping settings
[Java] Thymeleaf Basic (Spring Boot)
Introduction to Spring Boot ① ~ DI ~
File upload with Spring Boot
Spring Boot starting with copy
Introduction to Spring Boot ② ~ AOP ~
CICS-Run Java application-(4) Spring Boot application
Spring Boot starting with Docker
Spring Boot + Springfox springfox-boot-starter 3.0.0 Use
Spring Boot DB related tips
Hello World with Spring Boot
Set cookies with Spring Boot
Use Spring JDBC with Spring Boot
Docker × Spring Boot environment construction
Major changes in Spring Boot 1.5
Add module with Spring Boot
Getting Started with Spring Boot
NoHttpResponseException in Spring Boot + WireMock
[Spring Boot] Send an email
Spring Boot performance related settings
Introduction to Spring Boot Part 1
Spring Boot External setting priority
Try using Spring Boot Security
[Java] [Spring] Spring Boot 1.4-> 1.2 Downgrade Note