Menu Docs
Página inicial do Docs
/ /

Tutorial: Paginar dados com Java e quakus

Este tutorial mostra como implementar técnicas de paginação em um aplicativo do Quarkus conectado ao MongoDB. Você aprenderá a usar o repositório de dados de Jakarta para criar pontos de extremidade de REST API com suporte para métodos de paginação baseados em offset e em cursor.

A paginação é uma técnica usada para dividir grandes conjuntos de dados em partes menores e mais gerenciáveis. Este tutorial implementa métodos de paginação baseados em offset e em cursor. A paginação baseada em offset utiliza números de página para recuperar subconjuntos específicos de dados, enquanto a paginação baseada em cursor utiliza um ponto de referência, ou um cursor, para navegar pelo conjunto de dados.

Este tutorial mostra como executar as seguintes ações:

  • Verifique os pré-requisitos

  • Criar um projeto Quartokus com as dependências necessárias

  • Configurar a conexão do MongoDB

  • Definir uma entidade de dados e um repositório

  • Implementar pontos de extremidade de REST API para paginação

  • Teste os pontos de extremidade da paginação

1

Antes de começar, conclua as seguintes tarefas de pré-requisito:

  • Instalar o Java 21

  • Install Maven

  • Configurar um cluster MongoDB , seja no MongoDB Atlas ou em uma instância local do Docker

Para iniciar uma instância local do MongoDB com Docker, execute o seguinte comando:

docker run --rm -d --name mongodb-instance -p 27017:27017 mongo

Alternativamente, você pode usar o MongoDB Atlas e implantar um cluster M0 gratuito. Para aprender como criar uma conta e um cluster do Atlas, consulte o guia Introdução ao MongoDB.

2

Navegue até o Gerador de Código Quarto e configure seu projeto com as seguintes configurações:

  1. Selecione seu grupo preferido e ID do artefato.

  2. Adicione as seguintes dependências:

    • Documento JNoSQL MongoDB (quarkus-jnosql-document-mongodb)

    • RESTEasy Reactive (quarkus-resteasy-reactive)

    • RESTEasy Reactive jackson (quarkus-resteasy-reactive-jackson)

    • OpenAPI (quarkus-smallrye-openapi)

  3. Gere o projeto, baixe o arquivo ZIP e extraia-o.

Observação

Se você não conseguir encontrar uma dependência no gerador, adicione-a manualmente ao arquivo pom.xml.

Depois de concluir a configuração, verifique se seu arquivo pom.xml inclui as seguintes dependências:

<dependencies>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-smallrye-openapi</artifactId>
</dependency>
<dependency>
<groupId>io.quarkiverse.jnosql</groupId>
<artifactId>quarkus-jnosql-document-mongodb</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy-reactive</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy-reactive-jackson</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-arc</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-junit5</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
3

Abra o arquivo application.properties e adicione as seguintes propriedades de configuração para conectar à sua instância MongoDB :

quarkus.mongodb.connection-string = <your connection string>
jnosql.document.database = fruits

Esta configuração permite que seu aplicativo se conecte ao cluster MongoDB na string de conexão especificada e use o banco de dados fruits.

Importante

Em ambientes de produção, habilite o controle de acesso e imponha a autenticação. Para obter mais informações, consulte a Lista de verificação de segurança.

Você pode substituir essas propriedades usando variáveis de ambiente, que permitem especificar diferentes configurações para desenvolvimento, teste e produção sem modificar seu código.

4

Crie uma classe de entidade Fruit no diretório src/main/java. O seguinte código define a entidade com campos id e name:

import jakarta.nosql.Column;
import jakarta.nosql.Convert;
import jakarta.nosql.Entity;
import jakarta.nosql.Id;
import org.eclipse.jnosql.databases.mongodb.mapping.ObjectIdConverter;
@Entity
public class Fruit {
@Id
@Convert(ObjectIdConverter.class)
private String id;
@Column
private String name;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Fruit{" +
"id='" + id + '\'' +
", name='" + name + '\'' +
'}';
}
public static Fruit of(String name) {
Fruit fruit = new Fruit();
fruit.setName(name);
return fruit;
}
}
5

Crie uma interface FruitRepository que estenda a classe BasicRepository . O código a seguir define métodos para paginação baseada em offset e cursor:

import jakarta.data.Sort;
import jakarta.data.page.CursoredPage;
import jakarta.data.page.Page;
import jakarta.data.page.PageRequest;
import jakarta.data.repository.BasicRepository;
import jakarta.data.repository.Find;
import jakarta.data.repository.OrderBy;
import jakarta.data.repository.Repository;
@Repository
public interface FruitRepository extends BasicRepository<Fruit, String> {
@Find
CursoredPage<Fruit> cursor(PageRequest pageRequest, Sort<Fruit> order);
@Find
@OrderBy("name")
Page<Fruit> offSet(PageRequest pageRequest);
long countBy();
}

O framework implementa automaticamente essa interface, permitindo que você execute operações de banco de dados sem escrever código boilerplate.

6

Crie uma classe SetupDatabase no diretório src/main/java. O seguinte código preenche o banco de dados com dados de amostra na inicialização e exclui os dados no desligamento:

import jakarta.enterprise.context.ApplicationScoped;
import jakarta.enterprise.event.Observes;
import io.quarkus.runtime.ShutdownEvent;
import io.quarkus.runtime.StartupEvent;
import org.jboss.logging.Logger;
import java.util.List;
@ApplicationScoped
public class SetupDatabase {
private static final Logger LOGGER = Logger.getLogger(SetupDatabase.class.getName());
private final FruitRepository fruitRepository;
public SetupDatabase(FruitRepository fruitRepository) {
this.fruitRepository = fruitRepository;
}
void onStart(@Observes StartupEvent ev) {
LOGGER.info("The application is starting...");
long count = fruitRepository.countBy();
if (count > 0) {
LOGGER.info("Database already populated");
return;
}
List<Fruit> fruits = List.of(
Fruit.of("apple"),
Fruit.of("banana"),
Fruit.of("cherry"),
Fruit.of("date"),
Fruit.of("elderberry"),
Fruit.of("fig"),
Fruit.of("grape"),
Fruit.of("honeydew"),
Fruit.of("kiwi"),
Fruit.of("lemon")
);
fruitRepository.saveAll(fruits);
}
void onStop(@Observes ShutdownEvent ev) {
LOGGER.info("The application is stopping...");
fruitRepository.deleteAll(fruitRepository.findAll().toList());
}
}
7

Crie uma classe FruitResource no diretório src/main/java. Em seguida, cole o seguinte código no arquivo da classe :

import jakarta.data.Sort;
import jakarta.data.page.PageRequest;
import jakarta.ws.rs.DefaultValue;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.QueryParam;
import jakarta.ws.rs.core.MediaType;
@Path("/fruits")
public class FruitResource {
private final FruitRepository fruitRepository;
private static final Sort<Fruit> ASC = Sort.asc("name");
private static final Sort<Fruit> DESC = Sort.desc("name");
public FruitResource(FruitRepository fruitRepository) {
this.fruitRepository = fruitRepository;
}
@Path("/offset")
@GET
@Produces(MediaType.APPLICATION_JSON)
public Iterable<Fruit> offset(@QueryParam("page") @DefaultValue("1") long page,
@QueryParam("size") @DefaultValue("2") int size) {
var pageRequest = PageRequest.ofPage(page).size(size);
return fruitRepository.offSet(pageRequest).content();
}
@Path("/cursor")
@GET
@Produces(MediaType.APPLICATION_JSON)
public Iterable<Fruit> cursor(@QueryParam("after") @DefaultValue("") String after,
@QueryParam("before") @DefaultValue("") String before,
@QueryParam("size") @DefaultValue("2") int size) {
if (!after.isBlank()) {
var pageRequest = PageRequest.ofSize(size).afterCursor(PageRequest.Cursor.forKey(after));
return fruitRepository.cursor(pageRequest, ASC).content();
} else if (!before.isBlank()) {
var pageRequest = PageRequest.ofSize(size).beforeCursor(PageRequest.Cursor.forKey(before));
return fruitRepository.cursor(pageRequest, DESC).stream().toList();
}
var pageRequest = PageRequest.ofSize(size);
return fruitRepository.cursor(pageRequest, ASC).content();
}
}

Esta classe define os seguintes pontos de extremidade:

  • /fruits/offset: suporta paginação baseada em offset usando o parâmetro de query page .

  • /fruits/cursor: suporta paginação baseada em cursor utilizando os parâmetros de consulta after e before.

Ambos os endpoints também aceitam o parâmetro de query do size para especificar o número de itens por página.

8

Execute o seguinte comando a partir do seu diretório de projeto para iniciar seu aplicativo Quarkus no modo de desenvolvimento:

./mvnw compile quarkus:dev
9

Em uma janela de terminal separada, use os seguintes comandos curl para testar o ponto de extremidade da paginação de deslocamento. Estes comandos solicitam diferentes páginas de dados de frutas.

Para buscar a primeira página, execute o seguinte comando:

curl --location http://localhost:8080/fruits/offset?page=1

Para buscar a segunda página, execute o seguinte comando:

curl --location http://localhost:8080/fruits/offset?page=2

Para buscar a quinta página, execute o seguinte comando:

curl --location http://localhost:8080/fruits/offset?page=5
10

Use os seguintes comandos curl para testar o ponto de extremidade da paginação do cursor. Estes comandos utilizam os parâmetros after e before para navegar pelo conjunto de dados.

Para buscar o conjunto inicial de frutas, execute o seguinte comando:

curl --location http://localhost:8080/fruits/cursor

Para buscar frutas com valores de campo name que vêm após "banana", execute o seguinte comando:

curl --location http://localhost:8080/fruits/cursor?after=banana

Para buscar frutas com valores de campo name que vêm antes de "date", execute o seguinte comando:

curl --location http://localhost:8080/fruits/cursor?before=date

Para saber mais sobre paginação no MongoDB, consulte o guia Paginar resultados na documentação do MongoDB Atlas.

Para saber mais sobre o Quarkus, consulte a documentação do Quarkus.

Voltar

Quarkus com Panache e MongoDB

Nesta página