Para agentes de IA: um índice de documentação está disponível em https://www.mongodb.com/pt-br/docs/llms.txt — as versões de markdown de todas as páginas estão disponíveis anexando .md a qualquer caminho de URL.

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:

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; @Entitypublic 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; @Repositorypublic 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; @ApplicationScopedpublic 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.