Last Modified 10.11.2022

Pagination

NumbersForPagination.java
package net.java_school.commons;

public class NumbersForPagination {

	private int prevBlock;
	private int firstPage;
	private int lastPage;
	private int nextBlock;
	private int totalPage;
	private int listItemNo;
	private int startRecord;
	private int endRecord;

	public int getPrevBlock() {
		return prevBlock;
	}
	public void setPrevBlock(int prevBlock) {
		this.prevBlock = prevBlock;
	}
	public int getFirstPage() {
		return firstPage;
	}
	public void setFirstPage(int firstPage) {
		this.firstPage = firstPage;
	}
	public int getLastPage() {
		return lastPage;
	}
	public void setLastPage(int lastPage) {
		this.lastPage = lastPage;
	}
	public int getNextBlock() {
		return nextBlock;
	}
	public void setNextBlock(int nextBlock) {
		this.nextBlock = nextBlock;
	}
	public int getTotalPage() {
		return totalPage;
	}
	public void setTotalPage(int totalPage) {
		this.totalPage = totalPage;
	}
	public int getListItemNo() {
		return listItemNo;
	}
	public void setListItemNo(int listItemNo) {
		this.listItemNo = listItemNo;
	}
	public int getStartRecord() {
		return startRecord;
	}
	public void setStartRecord(int startRecord) {
		this.startRecord = startRecord;
	}
	public int getEndRecord() {
		return endRecord;
	}
	public void setEndRecord(int endRecord) {
		this.endRecord = endRecord;
	}

}
Paginator.java
/*
 * ----------------Design--------------------------------------------
 * [First] [Prev] 11 12 13 14 15 16 17 18 19 20 [Next] [Last]
 *
 * ----------------Numbers for pagination--------------------------------------
 * [First] -- 1
 * [Prev]  -- prevBlock
 * 11      -- firstPage (within current block)
 * 20      -- lastPage (within current block)
 * [Next]  -- nextBlock
 * [Last]  -- totalPage (totalPage is equal to the final page number)
 *
 * -----------------Number for design-------------------------------------
 * listItemNo  -- The number to append to the first item in the list (Not persistent data)
 *
 * ------------------Numbers for fetch query-------------------
 * startRecord -- First record number on the current page
 * endRecord   -- Last record number on the current page
 */
package net.java_school.commons;

import java.util.List;

public interface Paginator {

	public int getTotalRecordCount(String searchWord);

	public List<?> getItems(String searchWord, int startRecord, int endRecord);

	public default NumbersForPagination getNumbersForPagination(int totalRecordCount, int page, int recordsPerPage, int pagesPerBlock) {

		NumbersForPagination numbers = new NumbersForPagination();

		int totalPage = totalRecordCount / recordsPerPage;
		if (totalRecordCount % recordsPerPage != 0) totalPage++;

		int totalBlock = totalPage / pagesPerBlock;
		if (totalPage % pagesPerBlock != 0) totalBlock++;

		int block = page / pagesPerBlock;
		if (page % pagesPerBlock != 0) block++;

		int firstPage = (block - 1) * pagesPerBlock + 1;
		int lastPage = block * pagesPerBlock;

		int prevBlock = 0;
		if (block > 1) prevBlock = firstPage - 1;

		int nextBlock = 0;
		if (block < totalBlock) nextBlock = lastPage + 1;
		if (block >= totalBlock) lastPage = totalPage;

		int listItemNo = totalRecordCount - (page - 1) * recordsPerPage;
		int startRecord = (page - 1) * recordsPerPage + 1;
		int endRecord = page * recordsPerPage;

		numbers.setPrevBlock(prevBlock);
		numbers.setFirstPage(firstPage);
		numbers.setLastPage(lastPage);
		numbers.setNextBlock(nextBlock);
		numbers.setTotalPage(totalPage);

		numbers.setListItemNo(listItemNo);

		numbers.setStartRecord(startRecord);
		numbers.setEndRecord(endRecord);

		return numbers;
	}
}

Usage

@Controller
public class HomeController implements Paginator {

	@Autowired
	private SomeService service;

	@Override
	public int getTotalRecordCount(String searchWord) {
		return service.getTotalRecordCount(searchWord);
	}

	@Override
	public List<Item> getItems(String searchWord, int startRecord, int endRecord) {
		return service.getItems(searchWord, startRecord, endRecord);
	}

	@GetMapping("/")
	public String index(Integer page, String searchWord, Model model) {
		if (page == null) return "redirect:/?page=1";

		//1. Get total record count (A total of the number of records)
		int totalRecordCount = getTotalRecordCount(searchWord);

		//2. Get numbers for pagination
		int recordsPerPage = 4;
		int pagesPerBlock = 10;
		NumbersForPagination numbers = 
			getNumbersForPagination(totalRecordCount, page, recordsPerPage, pagesPerBlock);

		//3. Get items to list on the page
		List<Item> items = 
			getItems(searchWord, numbers.getStartRecord(), numbers.getEndRecord());

		model.addAttribute("items", items);
		model.addAttribute("prevBlock", numbers.getPrevBlock());
		model.addAttribute("nextBlock", numbers.getNextBlock());
		model.addAttribute("firstPage", numbers.getFirstPage());
		model.addAttribute("lastPage", numbers.getLastPage());
		model.addAttribute("totalPage", numbers.getTotalPage());

		return "index";
	}

}
Related Articles