栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

使用 Spring Boot、ThymeLeaf、Spring Data JPA、Hibernate、MySQL 进行分页和排序

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

使用 Spring Boot、ThymeLeaf、Spring Data JPA、Hibernate、MySQL 进行分页和排序

在前面的教程中,我们使用Spring Boot和 Thymeleaf 开发了一个 CRUD Web 应用程序。

在本教程中,我们将扩展spring boot CRUD web 应用程序,并使用 spring boot、thymeleaf、spring data JPA、Hibernate 和 MySQL 数据库实现分页和排序操作。

如您所知,分页允许用户一次查看一小部分数据(一页),排序允许用户以更有条理的方式查看数据。分页和排序都可以帮助用户更轻松、更方便地消费信息。

让我们从可以从本教程下载的员工管理系统项目开始,该项目基于 Spring Boot、Spring Data JPA、Hibernate、Thymeleaf 和 MySQL 数据库。

先决条件  带有 Thymeleaf、Spring MVC、Spring Data JPA、Hibernate、MySQL 的 Spring Boot CRUD Web 应用程序

项目要求 这是实现员工列表页面(员工管理系统) 的分页和排序的高级项目需求。  用户应该能够:
  • 在员工列表页面上执行分页
  • 在员工列表页面上进行排序

我们将建造什么? 我们将扩展spring boot CRUD web 应用程序,并使用 spring boot、thymeleaf、spring data JPA、Hibernate 和 MySQL 数据库实现分页和排序。

下面的截图总结了我们将在本教程中开发的分页和排序操作。

分页:

 

排序:
首先,我们将逐步实现分页操作,然后我们将完成排序操作。

一、分页实现

了解 Spring Data JPA 的分页 API 要使用 Spring Data JPA 提供的分页和排序 API,您的存储库接口必须扩展 PagingAndSortingRepository 接口,该接口定义了以下几个方法(T 指的是实体类):
@NoRepositoryBean
public interface PagingAndSortingRepository < T, ID > extends CrudRepository < T, ID > {

    
    Iterable < T > findAll(Sort sort);

    
    Page < T > findAll(Pageable pageable);
}

JpaRepository 接口扩展 了 PagingAndSortingRepository 接口,因此如果您的存储库接口的类型为 JpaRepository,则无需对其进行更改。 例如,使用以下命令从数据库中获取第一页,每页 5 个项目:
int pageNumber = 1;
int pageSize = 5;
Pageable pageable = PageRequest.of(pageNumber, pageSize);
 
Page page = repository.findAll(pageable);

然后就可以得到实际内容如下:
List listEmployees = page.getContent();

使用 Page 对象,您可以根据给定的页面大小了解数据库中的总行数和总页数:
long totalItems = page.getTotalElements();
int totalPages = page.getTotalPages();

此信息对于使用 Thymeleaf 模板在视图中实现分页很有用。

分页的后端更改

EmployeeService.java 接口更改 在此接口中添加以下方法:
Page findPaginated(int pageNo, int pageSize);

完整代码:
package net.javaguides.springboot.service;

import java.util.List;

import org.springframework.data.domain.Page;

import net.javaguides.springboot.model.Employee;

public interface EmployeeService {
    List < Employee > getAllEmployees();
    void saveEmployee(Employee employee);
    Employee getEmployeeById(long id);
    void deleteEmployeeById(long id);
    Page < Employee > findPaginated(int pageNo, int pageSize);
}

EmployeeServiceImpl.java 类更改 将以下方法添加到 EmployeeServiceImpl 类:
@Override
public Page findPaginated(int pageNo, int pageSize) {
 Pageable pageable = PageRequest.of(pageNo - 1, pageSize);
 return this.employeeRepository.findAll(pageable);
}

EmployeeController.java 类更改 将以下处理程序方法添加到 EmployeeController 类以执行分页:
@GetMapping("/page/{pageNo}")
public String findPaginated(@PathVariable(value = "pageNo") int pageNo, Model model) {
    int pageSize = 5;

    Page < Employee > page = employeeService.findPaginated(pageNo, pageSize);
    List < Employee > listEmployees = page.getContent();

    model.addAttribute("currentPage", pageNo);
    model.addAttribute("totalPages", page.getTotalPages());
    model.addAttribute("totalItems", page.getTotalElements());
    model.addAttribute("listEmployees", listEmployees);
    return "index";
}

此外,我们需要对现有方法进行更改,如下所示:
// display list of employees
@GetMapping("/")
public String viewHomePage(Model model) {
 return findPaginated(1, model);  
}

分页的前端更改 将以下分页代码添加到 index.html:
 1}">
    
        
            Total Rows: [[${totalItems}]]
        
        
            
      [[${i}]]
      [[${i}]]    
            
        
        
            Next
            Next
        

        
            Last
            Last
        
    

完整代码:




    
    Employee Management System

    





    
        Employees List

         Add Employee 

        
Employee First Name Employee Last Name Employee Email Actions
Update Delete
1}"> Total Rows: [[${totalItems}]] [[${i}]] [[${i}]]     Next Next Last Last

2.排序实现

了解 Spring Data JPA 的排序 API Spring Data JPA 提供了 PagingAndSortingRepository 接口,该接口支持使用以下 API 进行排序和分页:
@NoRepositoryBean
public interface PagingAndSortingRepository < T, ID > extends CrudRepository < T, ID > {

    
    Iterable < T > findAll(Sort sort);

    
    Page < T > findAll(Pageable pageable);
}

用户将能够通过单击表格的列标题对员工列表进行排序。  首先,像这样创建一个 Sort 对象:
Sort sort = Sort.by(“fieldName”).ascending();

这将按 fieldName 升序对结果进行排序。 fieldName 必须与实体类中声明的字段名称匹配。  我们还可以按多个字段排序,例如:
Sort sort = Sort.by("fieldName1").ascending().and(Sort.by("fieldName2").descending());

然后我们通过 Sort 对象来创建一个 Pageable ,如下所示:
Pageable pageable = PageRequest.of(pageNum - 1, pageSize, sort);

让我们在示例部分了解更多。

用于排序的后端更改

EmployeeService.java 接口更改 让我们在现有方法中添加两个字段:
Page findPaginated(int pageNo, int pageSize, String sortField, String sortDirection);

完整代码:
package net.javaguides.springboot.service;

import java.util.List;

import org.springframework.data.domain.Page;

import net.javaguides.springboot.model.Employee;

public interface EmployeeService {
    List < Employee > getAllEmployees();
    void saveEmployee(Employee employee);
    Employee getEmployeeById(long id);
    void deleteEmployeeById(long id);
    Page < Employee > findPaginated(int pageNo, int pageSize, String sortField, String sortDirection);
}

EmployeeServiceImpl.java 类更改 以下方法中实现的排序逻辑:
@Override
public Page findPaginated(int pageNo, int pageSize, String sortField, String sortDirection) {
    Sort sort = sortDirection.equalsIgnoreCase(Sort.Direction.ASC.name()) ? Sort.by(sortField).ascending() :
     Sort.by(sortField).descending();
 
    Pageable pageable = PageRequest.of(pageNo - 1, pageSize, sort);
    return this.employeeRepository.findAll(pageable);
}

完整代码:
package net.javaguides.springboot.service;

import java.util.List;
import java.util.Optional;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;

import net.javaguides.springboot.model.Employee;
import net.javaguides.springboot.repository.EmployeeRepository;

@Service
public class EmployeeServiceImpl implements EmployeeService {

    @Autowired
    private EmployeeRepository employeeRepository;

    @Override
    public List < Employee > getAllEmployees() {
        return employeeRepository.findAll();
    }

    @Override
    public void saveEmployee(Employee employee) {
        this.employeeRepository.save(employee);
    }

    @Override
    public Employee getEmployeeById(long id) {
        Optional < Employee > optional = employeeRepository.findById(id);
        Employee employee = null;
        if (optional.isPresent()) {
            employee = optional.get();
        } else {
            throw new RuntimeException(" Employee not found for id :: " + id);
        }
        return employee;
    }

    @Override
    public void deleteEmployeeById(long id) {
        this.employeeRepository.deleteById(id);
    }

    @Override
    public Page < Employee > findPaginated(int pageNo, int pageSize, String sortField, String sortDirection) {
        Sort sort = sortDirection.equalsIgnoreCase(Sort.Direction.ASC.name()) ? Sort.by(sortField).ascending() :
            Sort.by(sortField).descending();

        Pageable pageable = PageRequest.of(pageNo - 1, pageSize, sort);
        return this.employeeRepository.findAll(pageable);
    }
}

EmployeeController.java 更改 让我们更改现有方法以提供对排序的支持:
@GetMapping("/page/{pageNo}")
public String findPaginated(@PathVariable(value = "pageNo") int pageNo,
    @RequestParam("sortField") String sortField,
    @RequestParam("sortDir") String sortDir,
    Model model) {
    int pageSize = 5;

    Page < Employee > page = employeeService.findPaginated(pageNo, pageSize, sortField, sortDir);
    List < Employee > listEmployees = page.getContent();

    model.addAttribute("currentPage", pageNo);
    model.addAttribute("totalPages", page.getTotalPages());
    model.addAttribute("totalItems", page.getTotalElements());

    model.addAttribute("sortField", sortField);
    model.addAttribute("sortDir", sortDir);
    model.addAttribute("reverseSortDir", sortDir.equals("asc") ? "desc" : "asc");

    model.addAttribute("listEmployees", listEmployees);
    return "index";
}

还为主页提供默认的排序字段和排序方向:
// display list of employees
    @GetMapping("/")
    public String viewHomePage(Model model) {
        return findPaginated(1, "firstName", "asc", model);
    }

完整代码:
package net.javaguides.springboot.controller;

import java.util.List;

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

import net.javaguides.springboot.model.Employee;
import net.javaguides.springboot.service.EmployeeService;

@Controller
public class EmployeeController {

    @Autowired
    private EmployeeService employeeService;

    // display list of employees
    @GetMapping("/")
    public String viewHomePage(Model model) {
        return findPaginated(1, "firstName", "asc", model);
    }

    @GetMapping("/showNewEmployeeForm")
    public String showNewEmployeeForm(Model model) {
        // create model attribute to bind form data
        Employee employee = new Employee();
        model.addAttribute("employee", employee);
        return "new_employee";
    }

    @PostMapping("/saveEmployee")
    public String saveEmployee(@ModelAttribute("employee") Employee employee) {
        // save employee to database
        employeeService.saveEmployee(employee);
        return "redirect:/";
    }

    @GetMapping("/showFormForUpdate/{id}")
    public String showFormForUpdate(@PathVariable(value = "id") long id, Model model) {

        // get employee from the service
        Employee employee = employeeService.getEmployeeById(id);

        // set employee as a model attribute to pre-populate the form
        model.addAttribute("employee", employee);
        return "update_employee";
    }

    @GetMapping("/deleteEmployee/{id}")
    public String deleteEmployee(@PathVariable(value = "id") long id) {

        // call delete employee method 
        this.employeeService.deleteEmployeeById(id);
        return "redirect:/";
    }


    @GetMapping("/page/{pageNo}")
    public String findPaginated(@PathVariable(value = "pageNo") int pageNo,
        @RequestParam("sortField") String sortField,
        @RequestParam("sortDir") String sortDir,
        Model model) {
        int pageSize = 5;

        Page < Employee > page = employeeService.findPaginated(pageNo, pageSize, sortField, sortDir);
        List < Employee > listEmployees = page.getContent();

        model.addAttribute("currentPage", pageNo);
        model.addAttribute("totalPages", page.getTotalPages());
        model.addAttribute("totalItems", page.getTotalElements());

        model.addAttribute("sortField", sortField);
        model.addAttribute("sortDir", sortDir);
        model.addAttribute("reverseSortDir", sortDir.equals("asc") ? "desc" : "asc");

        model.addAttribute("listEmployees", listEmployees);
        return "index";
    }
}

排序的前端更改

索引.html 我们通过使用以下代码添加超链接来使表格的标题列可排序:

      
       Employee First Name
     
     
     
       Employee Last Name
     
     
     
       Employee Email
     
      Actions 

我们还需要更改分页部分以提供排序支持,例如:
 1}">
   
    
     Total Rows: [[${totalItems}]] 
    
    
     
      [[${i}]]
      [[${i}]]     
     
    
    
     Next
     Next
    
    
     
        Last
     Last
        
   
  

完整代码:




Employee Management System


 



 
 Employees List
 
  Add Employee 
 
  
Employee First Name Employee Last Name Employee Email Actions
Update Delete
1}"> Total Rows: [[${totalItems}]] [[${i}]] [[${i}]]     Next Next Last Last

GitHub 存储库链接
您可以从我的 GitHub 存储库下载/克隆本教程的源代码, 网址为 https://github.com/RameshMF/springboot-thymeleaf-crud-pagination-sorting-webapp.git

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/873784.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号