Join us at MongoDB.local London on 7 May to unlock new possibilities for your data. Use WEB50 to save 50%.
Register now >
Docs Menu
Docs Home
/ /

Tutorial: paginar datos con Java y Quarkus

Este tutorial te muestra cómo implementar técnicas de paginación en una aplicación Quarkus conectada a MongoDB. Aprenderás a usar el repositorio de Jakarta Data para crear endpoints de REST API que admitan tanto métodos de paginación basados en offset como en cursor.

La paginación es una técnica utilizada para dividir conjuntos de datos grandes en fragmentos más pequeños y manejables. Este tutorial implementa métodos de paginación basados en desplazamiento y basados en cursor. La paginación basada en compensación utiliza números de página para recuperar subconjuntos específicos de datos, mientras que la paginación basada en cursor utiliza un punto de referencia, o un cursor, para navegar por el conjunto de datos.

Esta guía muestra cómo realizar las siguientes acciones:

  • Verifique los requisitos previos

  • Crea un proyecto Quarkus con las dependencias necesarias

  • Configura la conexión de MongoDB

  • Define una entidad de datos y un repositorio

  • Implementa endpoints de REST API para paginación

  • Pruebe los puntos finales de paginación

1

Antes de comenzar, complete las siguientes tareas previas:

  • Instala Java 21

  • Install Maven

  • Configura un clúster de MongoDB, ya sea en MongoDB Atlas o en una instancia local de Docker

Para iniciar una instancia local de MongoDB con Docker, debes ejecutar el siguiente comando:

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

Como alternativa, puede utilizar MongoDB Atlas e implementar un clúster M0 gratuito. Para obtener información sobre cómo crear una cuenta y un clúster de Atlas, consulta la guía MongoDB Primeros pasos.

2

Navegue hasta el Generador de código Quarkus y configure su proyecto con la siguiente configuración:

  1. Seleccione el ID de grupo y artefacto que prefiera.

  2. Agrega las siguientes dependencias:

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

    • RESTEasy Reactive (quarkus-resteasy-reactive)

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

    • OpenAPI (quarkus-smallrye-openapi)

  3. Genera el proyecto, descarga el archivo ZIP y extrae su contenido.

Nota

Si no puede encontrar una dependencia en el generador, agréguela manualmente al archivo pom.xml.

Después de completar la configuración, verifique que su archivo pom.xml incluya las siguientes dependencias:

<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

Abre el archivo application.properties y añade las siguientes propiedades de configuración para conectarte a tu instancia de MongoDB:

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

Esta configuración permite que tu aplicación se conecte al clúster de MongoDB en la cadena de conexión especificada y utilice la base de datos fruits.

Importante

En los entornos de producción, habilitar el control de acceso y aplicar la autenticación. Para más información, consulta la Lista de verificación de seguridad.

Puedes anular estas propiedades utilizando variables de entorno, lo que te permite especificar diferentes configuraciones para desarrollo, pruebas y producción sin modificar tu código.

4

Crea una clase de entidad Fruit en el directorio src/main/java. El siguiente código define la entidad con los campos id y 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

Crea una interfaz de FruitRepository que extienda la clase BasicRepository. El siguiente código define métodos tanto para la paginación basada en offset como en 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();
}

El framework implementa esta interfaz automáticamente, permitiéndote realizar operaciones en la base de datos sin escribir código repetitivo.

6

Crea una clase SetupDatabase en el directorio src/main/java. El siguiente código llena la base de datos con datos de muestra al inicio y elimina los datos al apagarse:

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

Crea una clase FruitResource en el directorio src/main/java. Luego, pega el siguiente código en el archivo de clase:

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 clase define los siguientes puntos finales:

  • /fruits/offsetAdmite la paginación basada en desplazamiento mediante el uso del parámetro de query page.

  • /fruits/cursorAdmite la paginación basada en el cursor mediante el uso de los parámetros de query after y before.

Ambos extremos también aceptan el parámetro de query size para especificar el número de elementos por página.

8

Ejecuta el siguiente comando desde el directorio del proyecto para iniciar tu aplicación Quarkus en modo de desarrollo:

./mvnw compile quarkus:dev
9

En una ventana de terminal separada, utilice los siguientes comandos curl para probar el extremo de paginación por desplazamiento. Estos comandos hacen solicitudes de diferentes páginas de datos de fruta.

Para obtener la primera página, ejecute el siguiente comando:

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

Para obtener la segunda página, ejecuta el siguiente comando:

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

Para obtener la quinta página, ejecuta el siguiente comando:

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

Utiliza los siguientes comandos curl para probar el endpoint de paginación por cursor. Estos comandos utilizan los parámetros after y before para navegar por el conjunto de datos.

Para obtener el conjunto inicial de frutas, ejecuta el siguiente comando:

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

Para recuperar frutas con valores de campo name posteriores a "banana", ejecuta el siguiente comando:

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

Para obtener frutas con valores de campo name que vienen antes de "date", ejecute el siguiente comando:

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

Para saber más sobre la paginación en MongoDB, consulte la guía Paginación de Resultados en la documentación de MongoDB Atlas.

Para aprender más sobre Quarkus, consulta la documentación de Quarkus.

Volver

Quarkus con Panache y MongoDB

En esta página