elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Trabajando con las ramas de git (tercera parte)


+  Foro de elhacker.net
|-+  Programación
| |-+  Desarrollo Web (Moderador: #!drvy)
| | |-+  [Aporte] Como usar MySQL en NodeJs (Codigo de ejemplo)
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: [Aporte] Como usar MySQL en NodeJs (Codigo de ejemplo)  (Leído 4,315 veces)
[u]nsigned


Desconectado Desconectado

Mensajes: 2.397

JS/Node developer


Ver Perfil WWW
[Aporte] Como usar MySQL en NodeJs (Codigo de ejemplo)
« en: 15 Mayo 2020, 03:56 am »

Hola, queria compartirles este Ejemplo basico de como implementar MySQL en Node. Usando Promesas y async/await para dominar la asincronia sin bloquear el Event Loop.

Archivo mysql.js contiene la conexión a MySQL.
Código
  1. const mysql = require("mysql");
  2.  
  3. const mysqlConnection = mysql.createConnection({
  4.  host: "localhost",
  5.  port: 3306,
  6.  user: "root",
  7.  password: "",
  8.  database: "",
  9. });
  10.  
  11. mysqlConnection.connect((err) => {
  12.  if (err) {
  13.    console.error("[DB] No se pudo conectar con MYSQL", err);
  14.  } else {
  15.    console.log("[DB] Conectado con MYSQL", mysqlConnection.threadId);
  16.  }
  17. });
  18.  
  19. module.exports = mysqlConnection;
  20.  

Archivo con la clase principal. Implementa las 5 funciones básicas de CRUD+L = Create/Crear, Read/Leer, Update/Modificar, Delete/Borrar, List/Listar

Código
  1. const MySQL = require("./mysql");
  2.  
  3. function list(table) {
  4.  return new Promise(async (resolve, reject) => {
  5.    const sql = `SELECT * FROM ${table}`;
  6.  
  7.    await MySQL.query(sql, (err, results) => {
  8.      if (err) {
  9.        console.error("[DB]", err);
  10.        return reject({ message: err, code: 401 });
  11.      }
  12.      return resolve(results);
  13.    });
  14.  });
  15. }
  16.  
  17. function get(table, id) {
  18.  return new Promise(async (resolve, reject) => {
  19.    const sql = `SELECT * FROM ${table} WHERE id=${id}`;
  20.  
  21.    await MySQL.query(sql, (err, results) => {
  22.      if (err) {
  23.        console.error("[DB]", err);
  24.        return reject({ message: err, code: 401 });
  25.      }
  26.      return resolve(results);
  27.    });
  28.  });
  29. }
  30.  
  31. function insert(table, data) {
  32.  return new Promise(async (resolve, reject) => {
  33.    try {
  34.      const fields = Object.keys(data);
  35.      const values = Object.values(data);
  36.  
  37.      if (fields.length === 0) {
  38.        return reject({ message: "Faltan datos", code: 400 });
  39.      }
  40.  
  41.      const sql = `INSERT INTO ${table} (${fields}) VALUES (${values.map(
  42.        (h) => `'${h}'`
  43.      )})`;
  44.  
  45.      await MySQL.query(sql, async (err, results) => {
  46.        if (err) return reject({ message: err.message, code: 400 });
  47.  
  48.        const insertedData = await get(table, results.insertId);
  49.  
  50.        return resolve(insertedData);
  51.      });
  52.    } catch (error) {
  53.      return reject(error);
  54.    }
  55.  });
  56. }
  57.  
  58. function update(table, id, data) {
  59.  return new Promise(async (resolve, reject) => {
  60.    try {
  61.      const fields = Object.keys(data);
  62.      const values = Object.values(data);
  63.  
  64.      if (fields.length === 0) {
  65.        return reject({ message: "Faltan datos", code: 400 });
  66.      }
  67.  
  68.      const sql = `UPDATE ${table} SET ? WHERE id=${id}`;
  69.  
  70.      const beforeUpdate = await get(table, id);
  71.  
  72.      await MySQL.query(sql, data, async (err, results) => {
  73.        if (err) return reject({ message: err.message, code: 400 });
  74.  
  75.        const updateData = await get(table, id);
  76.  
  77.        return resolve({ ...results, beforeUpdate, updateData });
  78.      });
  79.    } catch (error) {
  80.      return reject(error);
  81.    }
  82.  });
  83. }
  84.  
  85. function remove(table, id) {
  86.  return new Promise(async (resolve, reject) => {
  87.    try {
  88.      const beforeUpdate = await get(table, id);
  89.  
  90.      if (beforeUpdate.length === 0)
  91.        return reject({ message: `El elemento ${id} no existe`, code: 403 });
  92.  
  93.      const sql = `DELETE FROM ${table} WHERE id=${id} LIMIT 1`;
  94.  
  95.      await MySQL.query(sql, async (err, results) => {
  96.        if (err) return reject({ message: err.message, code: 400 });
  97.  
  98.        return resolve({ ...results, beforeUpdate });
  99.      });
  100.    } catch (error) {
  101.      return reject(error);
  102.    }
  103.  });
  104. }
  105.  
  106. module.exports = {
  107.  list,
  108.  get,
  109.  insert,
  110.  update,
  111.  remove,
  112. };
  113.  
  114.  

Esta clase no tiene ningún tipo de validación, eso se debería hacer en otra capa, como por ejemplo en el controlador con @hapi/joi.

Para usarse simplemente debe importarse este modulo desde otro e invocar a la función CRUDL, por ejemplo

Ejemplo de Uso
Código
  1. const db = require("./db.js"); // suponiendo que el archivo anterior se llame "db.js y
  2.                                           // ademas este ubicado en el mismo directorio que el presente codigo.
  3.  
  4. // Usar como funcion asincrona que debuelve un resultado o un error
  5. // Operacion CRUDL: Listar la tabla 'usuarios' completa
  6. // SIEMPRE dentro de una funcion async
  7.  
  8. async function getUsers(){
  9.    const myUsers = await db.get('usuarios')
  10.    return await db.get('usuarios')
  11.    // return await db.get('usuarios')
  12. }
  13.  
  14. console.log(getUsers())
  15.  
  16. // O usar como funciones que devuelven promesas, y gestionarla con then/cath:
  17. // Operacion CRUDL: (D) Borrar el registro de la tabla 'usuarios' cuyo id sea igual a '666'
  18.  
  19. db.remove('usuarios', 666)//Borrar usuario con id 666
  20. .then(users=>{
  21.    // Se borro el usuario, hacer algo
  22.    console.log(`Se borro el user 666`)
  23. })
  24. .catch(error=>{
  25.   console.log(error)
  26. })
  27.  

Por ultimo, como tambien hago frontend, una cosa muy util es poder deshacer cualquier accion con un solo click, por cuestiones de UX/UI es una forma muy poderosa de fidelizar al usuario.

Por eso en las consultas 'remove' y 'update' se devuelve un objeto beforeUpdate y updateData

Código
  1. "beforeUpdate": [
  2.            {
  3.                "id": 14,
  4.                "nombre": "Departamento de Coordinacion y Gestion Cooperativa",
  5.                "responsable": ""
  6.            }
  7.        ]
  8.  

Eso es muy util para revertir la ejecucion de la queri con un simple boton o 'call to action' como tiene gmail.




En línea

No hay atajo ante la duda, el misterio se hace aquí...
Se hace carne en cada uno, el misterio es existir!
MinusFour
Moderador Global
***
Desconectado Desconectado

Mensajes: 5.529


I'm fourth.


Ver Perfil WWW
Re: [Aporte] Como usar MySQL en NodeJs (Codigo de ejemplo)
« Respuesta #1 en: 15 Mayo 2020, 04:53 am »

El paquete de mysql en node.js no usa promesas hasta donde yo tengo entendido. Por eso existe promise-mysql (que es un wrapper sobre mysql, aunque quizás sea mejor ver el paquete de mysql2 en su lugar (porque ya adopta promesas). De esa forma ya no tienes que preocuparte por promisificar los metodos.

await trabaja con promesas. Puedes usar la instrucción para envolver valores en promesas pero en tu código, await nunca espera a que la callback de mysql.query sea llamada. Si funciona con tus get porque si regresa promesas (que se resuelven de manera asincrona).


En línea

[u]nsigned


Desconectado Desconectado

Mensajes: 2.397

JS/Node developer


Ver Perfil WWW
Re: [Aporte] Como usar MySQL en NodeJs (Codigo de ejemplo)
« Respuesta #2 en: 19 Mayo 2020, 10:16 am »

Es cierto, normalmente se usa mysql2, de hecho es lo que usan todos los orm como Sequelize.

Pero era a modo de ejemplo, para los que recién empiezan en node. Ademas yo me acostumbre a trabajar así en express, encerrando todo en promesas, que es la forma correcta para luego usar middlewares a diferentes niveles (auth, error, routing, etc)

Citar
await trabaja con promesas. Puedes usar la instrucción para envolver valores en promesas pero en tu código, await nunca espera a que la callback de mysql.query sea llamada. Si funciona con tus get porque si regresa promesas (que se resuelven de manera asincrona).

No entendi del todo, pero las callbacks que mysql.query los uso asi por lo que te comentaba antes, para poder manejarlos mejor a nivel de middleware.

Quizás omiti el pequeño (o fundamental ) detalle de que este código esta pensado exclusivamente para usarse con el framework express.
En línea

No hay atajo ante la duda, el misterio se hace aquí...
Se hace carne en cada uno, el misterio es existir!
MinusFour
Moderador Global
***
Desconectado Desconectado

Mensajes: 5.529


I'm fourth.


Ver Perfil WWW
Re: [Aporte] Como usar MySQL en NodeJs (Codigo de ejemplo)
« Respuesta #3 en: 19 Mayo 2020, 14:16 pm »

No entendi del todo, pero las callbacks que mysql.query los uso asi por lo que te comentaba antes, para poder manejarlos mejor a nivel de middleware.

Quizás omiti el pequeño (o fundamental ) detalle de que este código esta pensado exclusivamente para usarse con el framework express.

Código
  1. (async function(){
  2.  await setTimeout(() => {
  3.    console.log('mensaje en callback');
  4.  }, 2000);
  5.  console.log('pasando a await');
  6. })();

Imprime 'pasando a await' primero y luego 'mensaje en callback'.

Código
  1. (async function(){
  2.  await (new Promise(ful => setTimeout(ful, 2000))).then(() => {
  3.    console.log('mensaje en callback');
  4.  }, 2000);
  5.  console.log('pasando a await');
  6. })();

Imprime 'mensaje en callback' primero y luego 'pasando a await'.

Lo que tu hiciste con mysql.query fue lo primero porque esa funcion no regresa una promesa.

Pudiste haber hecho:

Código
  1. let query = sql => new Promise((ful, rej) => {
  2.  mysql.query(sql, (err, res) => {
  3.    if(err) rej(err);
  4.    ful(res);
  5.  });
  6. });

Y despsués simplemente:

Código
  1. query(sql).then(res => {
  2.   /* resultados aqui */
  3. });

Y para esta función si puedes usar await (correctamente).

Código
  1. (async function(){
  2.  let resultados = await query(sql);
  3. })();

Casi no es necesario trabajar con new Promise. Es preferible usar las librerias que promisifican las APIs de manera especifica o de manera general. Node por ejemplo tiene util.promisify

Lo que significa que pudiste haber hecho algo como:

Código
  1. let query = util.promisify(mysql.query.bind(mysql));

Y asi no tienes que trabajar con new Promise.
En línea

[u]nsigned


Desconectado Desconectado

Mensajes: 2.397

JS/Node developer


Ver Perfil WWW
Re: [Aporte] Como usar MySQL en NodeJs (Codigo de ejemplo)
« Respuesta #4 en: 20 Mayo 2020, 07:46 am »

Muchas gracias.
En línea

No hay atajo ante la duda, el misterio se hace aquí...
Se hace carne en cada uno, el misterio es existir!
Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
[Aporte-C][Avance] Instrucciones de la VM con ejemplo
Programación C/C++
Miky Gonzalez 1 1,607 Último mensaje 8 Septiembre 2013, 20:35 pm
por Khronos14
[APORTE] Ejemplo de un LL-Hook para el Mouse.
.NET (C#, VB.NET, ASP)
Eleкtro 7 4,380 Último mensaje 26 Septiembre 2014, 16:41 pm
por Eleкtro
codigo nodejs y el resultado mostrarlo
Desarrollo Web
bengy 7 4,220 Último mensaje 14 Septiembre 2016, 16:32 pm
por bengy
Varias Aplicaciones en NodeJS ¿Qué puertos usar?
Desarrollo Web
Ali Baba 2 2,269 Último mensaje 28 Septiembre 2016, 15:04 pm
por Ali Baba
[APORTE]: Cómo usar urls amigables con el servidor web incorporado a PHP
PHP
mchojrin 0 1,642 Último mensaje 19 Julio 2019, 00:54 am
por mchojrin
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines