TiiL Tutorials
@TinhocTiiL

Bài 7: Springboot- Thymeleaf: Phân trang trình bày danh sách đối tượn

Hướng dẫn kỹ thuật phân trang hiển thị dữ liệu khi danh sách đối tượng dài.

1. Thêm dependency Data vào file pom.xml để có hàm thư viện cho việc phân trang

<dependency>
		    <groupId>org.springframework.data</groupId>
		    <artifactId>spring-data-commons</artifactId>
		    <version>2.3.2.RELEASE</version>
</dependency>

2. Ở bài này, ta xây dựng thêm tầng dịch vụ (service) dùng đề cung cấp dữ liệu cho Controller

  • Định nghĩa Interface
package thomc.DisplayListObjectPagination.services;

import org.springframework.stereotype.Service;
import thomc.DisplayListObjectPagination.models.SinhVien;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
@Service
public interface SinhvienService {
	public Page<SinhVien> findPaginated(Pageable pageable);
}
  • Thực thi
package thomc.DisplayListObjectPagination.services;

import org.springframework.stereotype.Service;

import thomc.DisplayListObjectPagination.models.SinhVien;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
@Service
public class SinhVienServiceImpl implements SinhvienService {
	// Ta hard-code dữ liệu tại đây  để tiện demo------ 
	static List<SinhVien> dsSinhVien=  new ArrayList<SinhVien>();
	static {
		dsSinhVien.add(new SinhVien("0001", "Mai Cường Thọ"));
		dsSinhVien.add(new SinhVien("0002", "Trần Văn Long"));
		dsSinhVien.add(new SinhVien("0003", "Phạm Thị Hoa"));
		dsSinhVien.add(new SinhVien("0004", "Lê Hùng Cương"));
		dsSinhVien.add(new SinhVien("0005", "Phan Minh ANh"));
		dsSinhVien.add(new SinhVien("0006", "Lê Thị Hoa"));
		dsSinhVien.add(new SinhVien("0007", "Bụi Văn Cúc"));
		dsSinhVien.add(new SinhVien("0008", "Lê Hồng Phong"));
		dsSinhVien.add(new SinhVien("0009", "Lệ Chu Lai"));
		dsSinhVien.add(new SinhVien("0010", "Nguyễn Hùng Cường"));
		dsSinhVien.add(new SinhVien("0011", "Lê Bá Vương"));
		dsSinhVien.add(new SinhVien("0012", "Trần Thống Nhất"));
	}
	//----------hết phần hard-code dữ liệu ---------------------
	@Override
	public Page<SinhVien> findPaginated(Pageable pageable) {
		int pageSize = pageable.getPageSize();
        int currentPage = pageable.getPageNumber();
        int startItem = currentPage * pageSize;
        List<SinhVien> list;

        if (dsSinhVien.size() < startItem) {
            list = Collections.emptyList();
        } else {
            int toIndex = Math.min(startItem + pageSize, dsSinhVien.size());
            list = dsSinhVien.subList(startItem, toIndex);
        }
        Page<SinhVien> sinhvienPage = new PageImpl<SinhVien>(list, PageRequest.of(currentPage, pageSize), dsSinhVien.size());
        return sinhvienPage;
	}

}

3. Xây dựng Controller

package thomc.DisplayListObjectPagination.controllers;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;

import thomc.DisplayListObjectPagination.models.SinhVien;
import thomc.DisplayListObjectPagination.services.SinhvienService;
@Controller
public class SinhVienController {
	 @Autowired
	 private SinhvienService svService;
	 
	@GetMapping("/danhsachSV")
	public String listStudent(Model model,  
								@RequestParam("page") Optional<Integer> page,
								@RequestParam("size") Optional<Integer> size) {
		final int currentPage = page.orElse(1);
        final int pageSize = size.orElse(5);
        Page<SinhVien> svPage = svService.findPaginated(PageRequest.of(currentPage - 1, pageSize));
		model.addAttribute("dsSV", svPage);
		
		int totalPages = svPage.getTotalPages();
        if (totalPages > 0) {
            List<Integer> pageNumbers = IntStream.rangeClosed(1, totalPages)
                .boxed()
                .collect(Collectors.toList());
            model.addAttribute("pageNumbers", pageNumbers);
        }
        return "sinhvien_getAll_Paged";
	}
}

 4. Trình bày tại View

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Danh sách sinh viên</title>
</head>
<body>
	<h1>Danh sách sinh viên</h1>
	<table border="1">
        <thead>
            <tr>
                <th> Mã số sinh viên </th>
                <th> Họ và tên </th>
            </tr>
        </thead>
        <tbody>
            <tr th:each="sv: ${dsSV}">
                <td th:text="${sv.maSoSV}" />
				<td th:text="${sv.hoVaTen}" />
            </tr>
        </tbody>
    </table>
    <div th:if="${dsSV.totalPages > 0}" th:each="pageNumber : ${pageNumbers}">
        <a th:href="@{/danhsachSV(size=${dsSV.size}, page=${pageNumber})}"
            th:text=${pageNumber}
            th:class="${pageNumber==dsSV.number + 1} ? active"></a>
    </div>
	
	
</body>
</html>

Full mã nguồn: https://github.com/maicuongtho/SOT383-Web2CLC/tree/main/DisplayListObjectPagination

Avatar
https://khoacntt.ntu.edu.vn/giang-vien/mai-cuong-tho

một GV Đại học. TiiL đã phụ trách một số môn học như: Lập trình Java, Phát triển web với Java, Lập trình thiết bị di động, Lập trình hệ thống nhúng và IoT.

Comments are closed.