Conexión a MySQL desde Node.js con y sin ORM

Preparación del entorno

Primero creamos la base de datos y la tabla que usaremos en los ejemplos:

CREATE DATABASE gestion_notas;
USE gestion_notas;

CREATE TABLE notas (
  id INT PRIMARY KEY AUTO_INCREMENT,
  titulo VARCHAR(255) NOT NULL,
  contenido TEXT NOT NULL,
  fecha_creacion TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

INSERT INTO notas (titulo, contenido) VALUES
  ('Primera nota', 'Contenido de ejemplo'),
  ('Segunda nota', 'Otro contenido');

Método con Pool de conexiones (mysql2)

Esta aproximación utiliza mysql2 con promesas y variables de antorno para la configuración.

Estructura de archivos

proyecto/
├── .env
├── db.js
├── servidor.js
└── package.json

Configuración de variables (.env)

DB_HOST=119.91.31.144
DB_USUARIO=test1
DB_CLAVE=tu_contraseña
DB_NOMBRE=test1
DB_PUERTO=3306

Módulo de conexión (db.js)

import { createPool } from 'mysql2/promise';
import { config } from 'dotenv';

config();

export const conexion = createPool({
  host: process.env.DB_HOST,
  user: process.env.DB_USUARIO,
  password: process.env.DB_CLAVE,
  database: process.env.DB_NOMBRE,
  port: parseInt(process.env.DB_PUERTO || '3306'),
  waitForConnections: true,
  connectionLimit: 10,
  queueLimit: 0
});

Operaciones CRUD (db.js)

export async function obtenerTodas() {
  const [filas] = await conexion.execute('SELECT * FROM notas ORDER BY fecha_creacion DESC');
  return filas;
}

export async function obtenerPorId(identificador) {
  const [resultado] = await conexion.execute(
    'SELECT * FROM notas WHERE id = ?',
    [identificador]
  );
  return resultado[0] || null;
}

export async function insertarNota(cabecera, descripcion) {
  const [respuesta] = await conexion.execute(
    'INSERT INTO notas (titulo, contenido) VALUES (?, ?)',
    [cabecera, descripcion]
  );
  return obtenerPorId(respuesta.insertId);
}

export async function eliminarNota(identificador) {
  await conexion.execute('DELETE FROM notas WHERE id = ?', [identificador]);
  return { eliminado: true };
}

API Express (servidor.js)

import express from 'express';
import { obtenerTodas, obtenerPorId, insertarNota, eliminarNota } from './db.js';

const aplicacion = express();
aplicacion.use(express.json());

aplicacion.get('/notas', async (peticion, respuesta, siguiente) => {
  try {
    const datos = await obtenerTodas();
    respuesta.json(datos);
  } catch (err) {
    siguiente(err);
  }
});

aplicacion.get('/notas/:identificador', async (peticion, respuesta, siguiente) => {
  try {
    const elemento = await obtenerPorId(peticion.params.identificador);
    if (!elemento) return respuesta.status(404).json({ error: 'No encontrado' });
    respuesta.json(elemento);
  } catch (err) {
    siguiente(err);
  }
});

aplicacion.post('/notas', async (peticion, respuesta, siguiente) => {
  try {
    const { titulo, contenido } = peticion.body;
    const creado = await insertarNota(titulo, contenido);
    respuesta.status(201).json(creado);
  } catch (err) {
    siguiente(err);
  }
});

aplicacion.delete('/notas/:identificador', async (peticion, respuesta, siguiente) => {
  try {
    await eliminarNota(peticion.params.identificador);
    respuesta.status(204).send();
  } catch (err) {
    siguiente(err);
  }
});

aplicacion.use((error, peticion, respuesta, siguiente) => {
  console.error(error);
  respuesta.status(500).json({ mensaje: 'Error interno del servidor' });
});

const PUERTO = process.env.PORT || 8080;
aplicacion.listen(PUERTO, () => {
  console.log(`Servidor activo en http://localhost:${PUERTO}`);
});

package.json

{
  "name": "api-mysql-ejemplo",
  "version": "1.0.0",
  "type": "module",
  "scripts": {
    "iniciar": "node servidor.js",
    "desarrollo": "nodemon servidor.js"
  },
  "dependencies": {
    "dotenv": "^16.3.0",
    "express": "^4.18.0",
    "mysql2": "^3.6.0"
  },
  "devDependencies": {
    "nodemon": "^3.0.0"
  }
}

Método con conexión simple (mysql)

Alternativa usando el paquete mysql con callbacks, todo en un único archivo:

const express = require('express');
const cors = require('cors');
const mysql = require('mysql');

const aplicacion = express();
aplicacion.use(cors());
aplicacion.use(express.json());

const db = mysql.createConnection({
  host: 'localhost',
  user: 'root',
  password: '',
  database: 'gestion_notas'
});

db.connect((err) => {
  if (err) {
    console.error('Fallo de conexión:', err.message);
    return;
  }
  console.log('Conectado a MySQL, threadId:', db.threadId);
});

aplicacion.get('/api/registros', (req, res) => {
  db.query('SELECT id, titulo, contenido, fecha_creacion FROM notas', 
    (error, resultados) => {
      if (error) {
        res.status(500).json({ error: error.message });
        return;
      }
      res.json(resultados);
    }
  );
});

aplicacion.post('/api/registros', (req, res) => {
  const { titulo, contenido } = req.body;
  db.query(
    'INSERT INTO notas (titulo, contenido) VALUES (?, ?)',
    [titulo, contenido],
    (error, resultado) => {
      if (error) {
        res.status(500).json({ error: error.message });
        return;
      }
      res.status(201).json({ id: resultado.insertId, titulo, contenido });
    }
  );
});

const PUERTO = process.env.PORT || 3000;
aplicacion.listen(PUERTO, () => {
  console.log(`Escuchando en puerto ${PUERTO}`);
});

Diferencias clave entre enfoques

Característica mysql2 con Pool mysql con conexión única
Manejo de async/await Nativo con promesas Requiere wrapper o callbacks
Randimiento concurrente Superior (reutiliza conexiones) Limitado a una conexión
Sintaxis de imports ES Modules CommonJS
Ideal para Producción y APIs REST Prototipos rápidos

Instalación de dependencias

# Para el primer método (mysql2)
npm install mysql2 dotenv express

# Para el segundo método (mysql)
npm install mysql express cors

# Ejecución
node servidor.js
# o con nodemon
npx nodemon servidor.js

Etiquetas: mysql2 MySQL nodejs express dotenv

Publicado el 8-8 20:57