1
resposta

[Dúvida] Usar paginação com CriteriaBuilder

Olá, eu tenho uma necessidade de desenvolver uma consulta que suporte o uso de alguns filtros de pesquisa sendo que parte destes o uso é opcional. Ao invés de ficar usando a interface JPARepository com o uso de métodos findByXYZ, estou querendo implementar um único método (tipo findAll(filtros)) com o uso do CriteriaBuilder. Neste caso, gostaria de saber como usar CriteriaBuilder com os recursos de paginação e sort disponíveis no Spring JPA. Pesquisei alguns exemplos na Internet e praticamente só encontro usando a interface de Repository, como se fosse a única solução disponível. Tem algum exemplo ou tutorial que eu possa me basear para fazer este tipo de implementação?

1 resposta

Olá, tudo bem?

Sim, é possível utilizar o CriteriaBuilder com os recursos de paginação e sort do Spring JPA. Para isso, você pode utilizar as classes Pageable e Sort do Spring Data. A classe Pageable representa as informações necessárias para realizar a paginação (número da página, tamanho da página, etc), enquanto a classe Sort representa as informações de ordenação.

Aqui está um exemplo de como você pode utilizar o CriteriaBuilder juntamente com o Pageable e o Sort:

public Page<Entidade> findAll(Filtros filtros, Pageable pageable, Sort sort) {
    CriteriaBuilder cb = entityManager.getCriteriaBuilder();
    CriteriaQuery<Entidade> query = cb.createQuery(Entidade.class);
    Root<Entidade> root = query.from(Entidade.class);
    Predicate predicate = cb.conjunction();

    // Aplica os filtros
    if (filtros.getCampo1() != null) {
        predicate = cb.and(predicate, cb.equal(root.get("campo1"), filtros.getCampo1()));
    }
    if (filtros.getCampo2() != null) {
        predicate = cb.and(predicate, cb.equal(root.get("campo2"), filtros.getCampo2()));
    }

    // Aplica a ordenação
    if (sort != null) {
        List<Order> orders = new ArrayList<>();
        for (Sort.Order order : sort) {
            if (order.isAscending()) {
                orders.add(cb.asc(root.get(order.getProperty())));
            } else {
                orders.add(cb.desc(root.get(order.getProperty())));
            }
        }
        query.orderBy(orders);
    }

    // Cria a consulta com os filtros e ordenação aplicados
    query.select(root).where(predicate);

    // Executa a consulta com a paginação
    TypedQuery<Entidade> typedQuery = entityManager.createQuery(query);
    typedQuery.setFirstResult((int) pageable.getOffset());
    typedQuery.setMaxResults(pageable.getPageSize());

    // Retorna os resultados paginados
    List<Entidade> resultList = typedQuery.getResultList();
    long total = count(filtros);
    return new PageImpl<>(resultList, pageable, total);
}

Nesse exemplo, a classe Filtros é uma classe que contém os filtros de pesquisa. A consulta utiliza o método equal do CriteriaBuilder para aplicar os filtros, e o método orderBy para aplicar a ordenação. A consulta é executada com a paginação utilizando o método setFirstResult para definir o índice do primeiro resultado e o método setMaxResults para definir o número máximo de resultados a serem retornados.

Espero que isso ajude! Qualquer dúvida, é só perguntar.