Spring Boot分页和排序示例

Spring Boot和Spring Data应用程序中使用分页和排序输入以及查询参数来学习仅请求和显示数据库中的数据块。

当我们在UI中以表格格式显示域数据时,最需要分页和排序。

分页由两个字段组成- 页面大小页码。对表中的多个字段中的一个进行排序。

1。 JPA实体

在本文中,我们以EmployeeEntity课堂为例。每个实体实例代表数据库中的员工记录。

EmployeeEntity.java
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name="TBL_EMPLOYEES")
public class EmployeeEntity {
    @Id
    @GeneratedValue
    private Long id;
    
    @Column(name="first_name")
    private String firstName;
    
    @Column(name="last_name")
    private String lastName;
    
    @Column(name="email", nullable=false, length=200)
    private String email;
    
    //Setters and getters
    @Override
    public String toString() {
        return "EmployeeEntity [id=" + id + ", firstName=" + firstName +
                ", lastName=" + lastName + ", email=" + email   + "]";
    }
}

2.分页和排序存储库

PagingAndSortingRepository是的扩展,CrudRepository提供了使用分页和排序抽象来检索实体的其他方法。它提供了两种方法:

  • Page findAll(Pageable pageable) –返回Page满足Pageable对象中提供的分页限制的实体。
  • 可迭代的findAll(Sort sort) –返回按给定选项排序的所​​有实体。这里不应用分页。
EmployeeRepository.java
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.stereotype.Repository;
import com.how2codex.demo.entity.EmployeeEntity;
@Repository
public interface EmployeeRepository
        extends PagingAndSortingRepository<EmployeeEntity, Long> {
}

3.接受分页和排序参数

通常,分页和排序参数是可选的,因此请求URL的一部分作为查询参数。如果任何API支持分页和排序,则始终为其参数提供默认值 -当客户端未选择指定任何分页或排序首选项时使用。

默认的分页和排序值应在API文档中明确记录。在用户界面中,这些默认值可以用不同的颜色突出显示。

页码值以0开头。因此,在UI中,如果您要从1显示页码,则不要忘记在获取记录时减去“ 1”。

在下面的spring mvc控制器中,我们接受使用pageNopageSizesortBy查询参数的分页和排序参数。另外,默认情况下,'10'将从数据库中的页码中提取'0'员工,并根据'id'字段对员工记录进行排序。

EmployeeController.java
@RestController
@RequestMapping("/employees")
public class EmployeeController
{
    @Autowired
    EmployeeService service;
    @GetMapping
    public ResponseEntity<List<EmployeeEntity>> getAllEmployees(
                        @RequestParam(defaultValue = "0") Integer pageNo,
                        @RequestParam(defaultValue = "10") Integer pageSize,
                        @RequestParam(defaultValue = "id") String sortBy)
    {
        List<EmployeeEntity> list = service.getAllEmployees(pageNo, pageSize, sortBy);
        return new ResponseEntity<List<EmployeeEntity>>(list, new HttpHeaders(), HttpStatus.OK);
    }
}

要执行分页和/或排序,我们必须创建实例org.springframework.data.domain.Pageable或将org.springframework.data.domain.Sort实例传递给该findAll()方法。

EmployeeService.java
@Service
public class EmployeeService
{
    @Autowired
    EmployeeRepository repository;
    
    public List<EmployeeEntity> getAllEmployees(Integer pageNo, Integer pageSize, String sortBy)
    {
        Pageable paging = PageRequest.of(pageNo, pageSize, Sort.by(sortBy));
        Page<EmployeeEntity> pagedResult = repository.findAll(paging);
        
        if(pagedResult.hasContent()) {
            return pagedResult.getContent();
        } else {
            return new ArrayList<EmployeeEntity>();
        }
    }
}

4.分页和排序技术

4.1。分页不排序

要仅在结果集中应用分页,我们将创建Pageable没有任何Sort信息的对象。

Pageable paging = PageRequest.of(pageNo, pageSize);
Page<EmployeeEntity> pagedResult = repository.findAll(paging);

4.2。分页分页

要仅在结果集中应用分页,我们将创建Pageable具有所需Sort列名的对象。

Pageable paging = PageRequest.of(pageNo, pageSize, Sort.by("email"));
Page<EmployeeEntity> pagedResult = repository.findAll(paging);

默认情况下,记录按DESCENDING顺序排序。若要选择升序,请使用.ascending()方法。

Pageable paging = PageRequest.of(pageNo, pageSize, Sort.by("email").ascending());
Page<EmployeeEntity> pagedResult = repository.findAll(paging);

4.3。仅排序

如果不需要分页,而只需要排序,则可以Sort为此创建对象。

Sort sortOrder = Sort.by("email");
List<EmployeeEntity> list = repository.findAll(sortOrder);

如果我们希望对多个列按sort进行排序,则也可以通过Sort使用简单的构建器模式步骤进行创建来实现。

Sort emailSort = Sort.by("email");
Sort firstNameSort = Sort.by("first_name");
Sort groupBySort = emailSort.and(firstNameSort);
List<EmployeeEntity> list = repository.findAll(groupBySort);

5.页面和切片之间的区别

5.1。页

findAll(Pageable pageable)默认情况下,该方法返回一个Page对象。一个Page对象提供了大量的比在当前页面的员工只列出其它额外的有用信息。

例如,一个Page对象具有总页数,和的数量,current page以及当前页是首页还是末页。

查找总页数会调用额外的count()查询,从而导致额外的开销成本。确保何时使用它。

5.2。切片

Slice与极为相似Page,不同之处在于它不提供数据库中的总页数。当我们不需要在UI中显示总数页面时,它有助于提高性能。

通常,Slice用于导航由下一页和上一页链接组成的情况。

要使用Slice,我们已经实现了自己的自定义方法。

EmployeeRepository.java
public interface EmployeeRepository extends CrudRepository<EmployeeEntity, Long>
{
    public Slice<EmployeeEntity> findByFirstName(String firstName, Pageable pageable);
}

请记住,这是我们使用的PagingAndSortingRepository默认返回类型为Page

Pageable paging = PageRequest.of(pageNo, pageSize, Sort.by("email").descending());
Slice<EmployeeEntity> slicedResult = repository.findByFirstName("alex", paging);
List<EmployeeEntity> employeeList = slicedResult.getContent();

6。 Spring Boot分页和排序演示

在此演示中,默认页码为0,页面大小为10,默认排序列为’id’。

现在一个接一个地调用这些URL并观察输出。

  • http:// localhost:8080 / employees?pageSize = 5
  • http:// localhost:8080 / employees?pageSize = 5&pageNo = 1
  • http:// localhost:8080 / employees?pageSize = 5&pageNo = 2
  • http:// localhost:8080 / employees?pageSize = 5&pageNo = 1&sortBy = email
  • http:// localhost:8080 / employees?pageSize = 5&pageNo = 1&sortBy = firstName

在有关如何使用Spring Data JPA进行分页和排序的注解中,向我提问。

saigon has written 1445 articles

Leave a Reply