首页 / Node.js 教程 / 数据库连接:MySQL 与 MongoDB

Node.js 教程

数据库连接:MySQL 与 MongoDB

本教程共 76 篇 · 第 48 篇 · 更新于 2026-07-25 · 约 4 分钟阅读

Node.jsMySQLMongoDB数据库连接池

48. 数据库连接:MySQL 与 MongoDB

本节目标:连接 MySQL 和 MongoDB,连接池和基础配置。

内存里的数据重启就丢,真实项目必须把数据持久化到数据库。本章介绍两种最常见的数据库:关系型的 MySQL 和文档型的 MongoDB,分别用官方推荐的驱动连上 Node.js。

MySQL:mysql2

Node.js 连 MySQL 首选 mysql2。它比旧版 mysql 快,原生支持 Promise,不用再自己包一层。

npm install mysql2

单连接 vs 连接池

单连接简单但性能差,生产环境必须用连接池:

import mysql from 'mysql2/promise';

const pool = mysql.createPool({
  host: 'localhost',
  user: 'root',
  password: 'yourpassword',
  database: 'test',
  waitForConnections: true,
  connectionLimit: 10,
  queueLimit: 0
});

const [rows] = await pool.execute('SELECT * FROM users WHERE id = ?', [1]);
console.log(rows);

connectionLimit: 10 表示池子里最多同时保持 10 个连接。请求来了拿一个,用完归还,而不是每次都新建 TCP 连接。数据库连接是昂贵资源,池化是必选项。

Warning

永远用 execute() 或者带 ? 占位符的查询,别用字符串拼接 SQL。后面章节会详细讲 SQL 注入,这里先记住:拼接 SQL 是定时炸弹。

建库建表

await pool.execute(`
  CREATE TABLE IF NOT EXISTS users (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(100) NOT NULL,
    email VARCHAR(100) NOT NULL UNIQUE,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
  )
`);

MongoDB:官方驱动

MongoDB 是文档型数据库,数据以 JSON-like 的 BSON 格式存储,没有固定的表结构,适合 schema 变化频繁的场景。

npm install mongodb

连接与基本操作:

import { MongoClient } from 'mongodb';

const uri = 'mongodb://localhost:27017';
const client = new MongoClient(uri);

await client.connect();
const db = client.db('myapp');
const users = db.collection('users');

// 插入
await users.insertOne({ name: 'Alice', email: 'alice@example.com' });

// 查询
const user = await users.findOne({ name: 'Alice' });
console.log(user);

// 关闭连接(优雅退出时)
await client.close();

连接字符串

本地开发用 mongodb://localhost:27017/myapp。如果有用户名密码:

mongodb://username:password@localhost:27017/myapp?authSource=admin

MongoDB Atlas(云托管)会给一个更长的连接串,直接复制粘贴即可。

选 MySQL 还是 MongoDB

场景推荐
数据结构固定、事务强、复杂查询多MySQL
数据结构灵活、快速迭代、海量日志/内容MongoDB
两者都要都可以,或者混用(MySQL 存核心业务,MongoDB 存日志)

很多项目早期用 MongoDB 快速试错,数据模型稳定后迁移到 MySQL,这也是常见的技术演化路径。

封装数据库模块

不管用哪种数据库,都建议把连接逻辑封装成独立模块,不要在控制器里直接 createPool

db/mysql.mjs

import mysql from 'mysql2/promise';

const pool = mysql.createPool({
  host: process.env.DB_HOST || 'localhost',
  user: process.env.DB_USER || 'root',
  password: process.env.DB_PASSWORD || '',
  database: process.env.DB_NAME || 'myapp',
  connectionLimit: 10
});

export default pool;

db/mongo.mjs

import { MongoClient } from 'mongodb';

const uri = process.env.MONGO_URI || 'mongodb://localhost:27017/myapp';
const client = new MongoClient(uri);
await client.connect();

export const db = client.db();

控制器里直接导入使用:

import pool from '../db/mysql.mjs';

export async function listUsers(ctx) {
  const [rows] = await pool.execute('SELECT * FROM users');
  ctx.body = { data: rows };
}
Note

数据库连接信息永远不要硬编码,走环境变量。开发环境用 .env 文件(配合 dotenv 包),生产环境由部署平台注入。