Node.js es un entorno de tiempo de ejecución como el motor JavaScript V8 de Chrome. Node.js es un entorno de tiempo de ejecución back-end, multiplataforma y de código abierto que se ejecuta fuera de un navegador web.
MySQL es un sistema de administración de bases de datos relacionales de código abierto que es rápido, confiable, flexible y robusto. Tanto MySQL como Node.js son opciones de moda al crear aplicaciones web. Otra ventaja de MySQL es que proporciona soporte integrado para utilidades como la paginación.
¿Qué es la paginación y por qué es importante?
La paginación no es más que dividir datos en partes o páginas discretas. Una página web que muestra miles de registros divididos en páginas se siente más atractiva e interactiva y mejor para el rendimiento de la aplicación. Por lo tanto, la paginación ayuda a una mejor visualización, un mejor rendimiento y una mejor experiencia del usuario al no abrumar al usuario con datos y evitar desplazamientos prolongados.
Podemos hacer tanto la paginación del lado del cliente como la paginación del lado del servidor. En este artículo, veremos un ejemplo de paginación del lado del servidor.
Paginación del lado del servidor: según IBM, la paginación del lado del servidor es para:
- Gran conjunto de datos.
- Carga de página inicial más rápida.
- Accesibilidad para aquellos que no ejecutan JavaScript.
- Lógica empresarial de vista compleja.
- Resiliencia a los cambios concurrentes.
La paginación del lado del servidor generalmente se realiza en el código de middleware (lógica comercial) o en la capa de la base de datos. La paginación del lado del servidor suele ser más desafiante que la del lado del cliente, pero se escala mejor.
Paginación del lado del cliente: la paginación del lado del cliente es adecuada cuando:
- El conjunto de datos es pequeño.
- Cargas de página subsiguientes más rápidas
- Los requisitos de clasificación y filtrado son totalmente compatibles (a menos que los resultados superen el tamaño máximo).
La paginación del lado del cliente es más rápida de implementar pero no es muy escalable.
¿Pasos para hacer la paginación del lado del servidor?
Vamos a ver un ejemplo de paginación del lado del servidor. Manejaremos la paginación en el nivel de la base de datos. Para la paginación usando MySQL, necesitamos usar la Cláusula LIMIT con el valor de Compensación. La cláusula de límite recupera solo una parte de los registros. La sintaxis básica de la cláusula Limit es la siguiente:
Select <column-names> From <table-names> Where <conditions> LIMIT <offset>, <number_of_records>;
El desplazamiento es opcional con un valor predeterminado de 0, pero puede obtener cualquier valor positivo menor que la cantidad de registros en el conjunto de datos.
Aplicación de ejemplo: construiremos una aplicación simple con Node.js, Express.js, MySQL y Sequelize ORM. Asegúrese de tener Node.js y MySQL en su sistema. Usaremos Visual Studio Code para desarrollar la aplicación.
Crear una carpeta de proyecto y cambiar la carpeta
mkdir PaginationExample cd PaginationExample
Inicializar la aplicación
npm init
Para generar el archivo package.json.
A continuación, instalamos express.js, sequelize y pug para las plantillas.
npm install -g express sequelize pug dotenv express-paginate
También requerimos instalar el paquete dotenv y express-paginate. El paquete Express-paginate expone varios métodos como href y middleware. Los detalles de las funciones se dan en la documentación.
Nuestra estructura de carpetas es la siguiente.
Para ejecutar la aplicación de Node, debemos ejecutar el siguiente comando desde la Terminal en Visual Studio Code.
node server.js
Si todo funciona correctamente, debería ver un resultado similar a este en la terminal:
Una vez que vea este mensaje, puede abrir un navegador e ir al enlace: localhost:8000
Hemos estructurado las llamadas en la aplicación, y deberíamos ver directamente una tabla con los registros y una opción para Paginar.
Código de aplicación: Veremos los archivos de código de aplicación capa por capa.
Archivo Server.js: El servidor.js es el archivo principal que contiene todas sus configuraciones relacionadas con Express y nuestra única ruta para obtener los registros y llamar al archivo de servicio. El archivo del servidor tiene el siguiente código.
Javascript
// Required External modules const express = require("express"); const path = require("path"); require("dotenv").config(); const paginate = require("express-paginate"); // Required code files const services = require("./service/services.js"); // Application Variables const app = express(); const port = 8000; // Server app.listen(port, () => { console.log(`App running on port ${port}.`); }); // Configuration app.set("views", path.join(__dirname, "./views")); app.set("view engine", "pug"); app.use("/static", express.static( path.join(__dirname, "public"))); app.use(paginate.middleware(10, 50)); // Routes app.get("/", (req, res) => { const limit = req.query.limit || 10; const offset = req.offset; services.findRecords({ offset: offset, limit: limit }).then((results) => { const pageCount = Math.ceil(results.count / limit); res.render("paginatedTable", { data: results.rows, pageCount, pages: paginate.getArrayPages(req) (3, pageCount, req.query.page), }); }); });
Archivos de Sequelize: hemos separado la configuración de la base de datos, el modelo de Sequelize y la llamada en tres archivos separados para facilitar el mantenimiento a medida que la aplicación escala.
- El archivo de Servicios contiene todas nuestras llamadas de Sequelize.
- models.js contiene la estructura de la tabla que usamos para nuestra consulta. Estamos usando la tabla nicer_but_slower_film_list de la base de datos SAKILA para nuestro ejemplo.
- El archivo dbconfig.js contiene el objeto Sequelize. Todo el código relacionado con los archivos está disponible en este repositorio.
- Sequelize proporciona un método incorporado: findAndCountAll, que es ideal para la paginación. El método findAndCountAll toma los argumentos offset y limit y devuelve el total de registros disponibles y los registros reales basados en el límite y el valor de compensación. El código es el siguiente:
dbconfig.js: dbconfig contiene el objeto Sequelize. Las propiedades para crear el objeto Sequelize provienen del archivo .env según la configuración de su base de datos. Aquí hemos creado un objeto de base de datos simple.
Javascript
const Sequelize = require("sequelize"); module.exports = new Sequelize({ dialect: "mysql", username: process.env.DB_USER, password: process.env.DB_PASS, host: process.env.DB_HOST, port: process.env.DB_PORT, database: process.env.DB_DATABASE, logging: (log) => console.log("logging:", log), });
models.js: El archivo models.js contiene la descripción de las tablas que estamos usando en nuestras consultas. Es una representación Sequelize de las tablas de bases de datos relacionales.
Javascript
var Sequelize = require("sequelize"); db = require("../config/dbconfig.js"); const nicer_but_slower_film_list = db.define( "nicer_but_slower_film_list", { FID: { type: Sequelize.SMALLINT, // To ensure that Sequelize // does not use id by default primaryKey: true, }, title: Sequelize.STRING, description: Sequelize.STRING, category: Sequelize.STRING, price: Sequelize.DECIMAL, length: Sequelize.SMALLINT, rating: Sequelize.ENUM("G", "PG", "PG-13", "R", "NC-17"), actors: Sequelize.STRING, }, { // This is to ensure that Sequelize // does not pluralize table names freezeTableName: true, // This is to ensure that Sequelize // does not add its own timestamp // variables in the query. timestamps: false, createdAt: false, updatedAt: false, } ); module.exports = nicer_but_slower_film_list;
services.js: el archivo de servicios contiene las llamadas Sequelize que realizamos. Este archivo contendría las llamadas de búsqueda, creación, actualización, eliminación de llamadas, etc. El archivo depende del objeto Sequelize (dbconfig.js) y el modelo Sequelize (models.js).
Javascript
const Sequelize = require("sequelize"); // Model file var model = require("../models/models.js"); // db Configuration db = require("../config/dbconfig.js"); let findRecords = async (req, res) => { return model.findAndCountAll({ offset: req.offset, limit: req.limit }); }; module.exports = { findRecords: findRecords };
Entonces, si el límite que establecemos es diez y el desplazamiento es 20 (es decir, los registros de la página 3), entonces la consulta formada por findAndCountAll y desenstringda en la base de datos es:
SELECCIONE `FID`, `título`, `descripción`, `categoría`, `precio`, `duración`, `puntuación`, `actores` FROM `mejor_pero_lenta_película_lista` AS `mejor_pero_lenta_película_lista` LÍMITE 20, 10;
La consulta da los siguientes resultados de la base de datos:
La salida que se muestra en la pantalla es la siguiente:
Interfaz de usuario de la aplicación: además de los archivos mencionados anteriormente, la estructura del proyecto también tiene la carpeta node_modules, los archivos de instalación node y express, y el archivo .env. El archivo .env contiene la información relacionada con la base de datos, como el nombre de usuario, la contraseña, el número de puerto de MySQL, etc., que usamos en el archivo dbconfig.js para crear el objeto de conexión Sequelize.
Interfaz de usuario: para manejar la interfaz de usuario, estamos utilizando la plantilla PUG. Usamos los métodos de paginación rápida para manejar los controles de paginación en la plantilla PUG. El código siguiente controla si se muestran o no los vínculos de los botones Anterior y Siguiente.
paginatedTable.pug: Esta es la interfaz de usuario con resultados paginados.
HTML
html head link(rel='stylesheet' href='https://getbootstrap.com/docs/4.4/dist/css/bootstrap.min.css') style include ../public/style.css body h1 Movies table thead tr th Title th Description th Category th Length th Rating th Actors tbody each dat in data tr td #{dat.title} td #{dat.description} td #{dat.category} td #{dat.length} td #{dat.rating} td #{dat.actors} if paginate.hasPreviousPages || paginate.hasNextPages(pageCount) .navigation.well-sm#pagination ul.pager if paginate.hasPreviousPages a(href=paginate.href(true)).prev i.fa.fa-arrow-circle-left | Previous if pages each page in pages a.btn.btn-default(href=page.url)= page.number if paginate.hasNextPages(pageCount) a(href=paginate.href()).next | Next i.fa.fa-arrow-circle-right script(src='https://code.jquery.com/jquery-3.4.1.slim.min.js') script(src='https://getbootstrap.com/docs/4.4/dist/js/bootstrap.bundle.min.js')
hasPrevious y hasNext son dos métodos expuestos por el paquete express-paginate, que devuelven valores booleanos. Según el valor de estos valores booleanos, la interfaz de usuario muestra los botones Siguiente y Anterior.
estilo.css
La hoja de estilo de la página es la siguiente:
CSS
table { width: 100%; border: 1px solid #fff; border-collapse: collapse; border-radius: 8px; } th, td { text-align: left; text-transform: capitalize; border: 1px solid darkgrey; color: black; } th { padding: 8px 10px; height: 48px; background-color: #808e9b; } td { padding: 6px 8px; height: 40px; } a:hover { background-color: #555; } a:active { background-color: black; } a:visited { background-color: #ccc; }
¿Cómo funciona exactamente la aplicación?
- La primera vez que accedemos a la URL localhost:8000, debido al middleware de paginación rápida, el valor Límite se establece en 10 de forma predeterminada y el desplazamiento se establece en 0. Por lo tanto, los primeros diez registros se recuperan de la base de datos y se muestran.
- Cuando el usuario pulsa el botón Siguiente o el número de página, es decir, 1, 2 o 3, el middleware de paginación calcula el desplazamiento. La fórmula para calcular el desplazamiento es simple:
pageNumber(we see in the URL on the UI) -1 * limit
Donde pageNumber comienza en 1.
- También podemos aumentar el límite hasta 50 registros. No podemos aumentar el límite más de 50 registros ya que lo hemos especificado como el límite máximo en la función de middleware. El límite se ha establecido en el archivo server.js.
app.use(paginate.middleware(10, 50));
Lanzar una consulta como esta: http://localhost:8000/?page=1&limit=500 no causará un error, pero la cantidad de registros mostrados seguirá siendo 50. También podemos mejorar la funcionalidad para mostrar algunos mensajes que solo Se pueden ver 50 registros a la vez.
Resumen: este artículo mostró cómo funciona la paginación con Node.js y MySQL usando una base de datos de muestra de MySQL. También vimos cómo podíamos limitar al usuario para que viera solo una cantidad determinada de registros en la página para no causar interrupciones en la interfaz de usuario. El código completo está disponible en el enlace de Github .
Publicación traducida automáticamente
Artículo escrito por reshmasathe y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA