← MySQL 数据库 创建 MySQL →

Node.js连接MySQL教程:环境搭建、连接配置与增删改查

著
原创 2026-10-13 Node.js 已有人查阅

一、前置准备:明确技术边界与环境要求

Node.js本身不内置MySQL驱动,它提供的是服务端JavaScript运行时。要让Node.js与MySQL通信,必须借助第三方驱动包。mysql是Node.js生态中使用时间较长、文档较完善的驱动之一,基于回调方式处理异步操作。它的特点是稳定、兼容性好,适合维护旧项目或对回调风格没有抵触的团队。如果新项目追求Promise与async/await的写法,可以优先考虑mysql2,它兼容mysql的大部分API,同时原生支持Promise。本教程以mysql包为主线,因为理解回调模式后再迁移到Promise风格并不困难。

开始之前,确认以下环境已经就绪:

  • Node.js已安装,终端中node-v与npm-v能正常输出版本号。

  • MySQLServer已安装并处于运行状态。

  • 一个代码编辑器,例如VisualStudioCode。

  • 具备JavaScript基础与SQL基本语句的读写能力。

二、初始化项目与安装驱动

新建项目目录并进入:

mkdir mysql-demo
cd mysql-demo

初始化package.json,用于记录项目信息与依赖:

npm init -y

安装MySQL驱动:

npm install mysql

安装完成后,package.json的dependencies中会出现mysql字段,node_modules目录也会生成。这一步看似简单,但有一个经验点值得注意:不要全局安装MySQL驱动。数据库连接属于项目级依赖,全局安装会导致不同项目之间版本冲突,也不利于团队协作时锁定版本。

三、创建数据库与连接配置

在Node.js连接之前,先在MySQL中创建目标数据库。打开MySQLWorkbench或命令行:

CREATE DATABASE companydb;
SHOW DATABASES;

确认companydb出现在数据库列表中。接着在项目根目录创建app.js,引入驱动并配置连接:

const mysql = require('mysql');

const connection = mysql.createConnection({
  host: 'localhost',
  user: 'root',
  password: 'your_password',
  database: 'companydb',
  port: 3306
});

连接参数说明:

参数 说明
host MySQL服务器主机名
user MySQL用户名
password 对应用户的密码
database 要连接的数据库名称
port MySQL服务端口,默认3306

这里有一个容易忽略的细节:password不要直接硬编码在业务代码中。实际项目应通过环境变量或配置文件注入,例如使用dotenv读取.env文件。硬编码密码一旦提交到代码仓库,数据库凭证就会泄露。

四、建立连接与执行SQL查询

配置完成后,调用connection.connect()建立连接:

connection.connect((err) => {
  if (err) {
    console.error('Connection Failed:', err.message);
    return;
  }
  console.log('Connected to MySQL Successfully');
});

运行:

node app.js

终端输出ConnectedtoMySQLSuccessfully表示连接成功。接着可以执行一条简单查询验证链路:

connection.query(
  'SELECT NOW() AS CurrentTime',
  (err, result) => {
    if (err) {
      console.log(err);
      return;
    }
    console.log(result);
  }
);

输出格式类似:

[ { CurrentTime: 2026-09-09T08:30:00.000Z } ]

这条查询的意义在于确认三件事:连接对象可用、SQL能发送到MySQL、结果能回传到Node.js回调。项目中,建议把这类验证查询放在开发初期完成,不要等到业务表建好后再排查连接问题。

五、创建表与数据操作

连接稳定后,可以执行建表语句:

const sql = `
CREATE TABLE employees(
  id INT AUTO_INCREMENT PRIMARY KEY,
  name VARCHAR(50),
  salary DECIMAL(10,2)
)`;

connection.query(sql, (err) => {
  if (err) throw err;
  console.log('Table Created Successfully');
});

建表之后,增删改查都通过connection.query()完成。下面给出一个插入与查询的组合示例,文件名可命名为code_01_crud.js:

connection.query(
  'INSERT INTO employees(name, salary) VALUES (?, ?)',
  ['code_01_张三', 8800.00],
  (err, result) => {
    if (err) throw err;
    console.log('Inserted ID:', result.insertId);

    connection.query(
      'SELECT * FROM employees WHERE id = ?',
      [result.insertId],
      (err, rows) => {
        if (err) throw err;
        console.log(rows);
      }
    );
  }
);

使用?占位符而不是字符串拼接,是防止SQL注入的基本手段。mysql包会自动对参数进行转义。把用户输入直接拼进SQL字符串,等于把数据库暴露给外部输入。

六、错误处理与常见连接故障

连接失败时,err.message会给出线索。以下是三类高频错误:

Accessdeniedforuser'root'@'localhost'

用户名或密码不正确,或者该用户没有从当前主机连接的权限。检查MySQL用户权限表,确认root是否允许localhost访问。

Unknowndatabase'companydb'

数据库不存在。连接参数中的database必须与MySQL中已创建的库名一致。

connectECONNREFUSED

MySQL服务未启动或端口不可达。确认MySQLServer服务正在运行,且port配置与实际监听端口一致。

在回调中统一处理错误,比在每个查询里写if(err)throwerr更利于维护。生产环境应把错误记录到日志系统,而不是直接抛出让进程崩溃。

七、关闭连接与连接池

单次脚本任务完成后,应关闭连接释放资源:

connection.end((err) => {
  if (err) {
    console.error('Error closing connection:', err.message);
    return;
  }
  console.log('MySQL Connection Closed.');
});

但如果应用需要频繁处理数据库请求,每次新建连接开销较大。这时应使用连接池:

const pool = mysql.createPool({
  host: 'localhost',
  user: 'root',
  password: 'your_password',
  database: 'companydb',
  port: 3306,
  connectionLimit: 10
});

pool.query('SELECT NOW() AS CurrentTime', (err, result) => {
  if (err) throw err;
  console.log(result);
});

连接池会复用已有连接,避免频繁握手。Web服务、API接口这类场景,连接池是更合理的选择。connection.end()对应的是单连接模式;连接池通常不需要手动关闭每个连接,进程退出时池会自行清理。

八、常用连接方法速查

方法 说明
mysql.createConnection() 按配置创建连接对象
connection.connect() 建立与MySQL的连接
connection.query() 执行SQL查询
connection.end() 关闭连接
mysql.createPool() 创建连接池
pool.query() 从池中取连接并执行查询

九、现在框架中的惯用写法

在Express、Koa、NestJS等框架中,通常不会在每个路由里直接写mysql.createConnection()。更常见的做法是:

  • 把连接池封装为独立模块,例如db.js,对外暴露query方法。

  • 通过环境变量管理数据库配置,区分开发、测试、生产环境。

  • 在应用启动时初始化连接池,在应用关闭时释放资源。

  • 使用mysql2/promise配合async/await,让异步代码更接近同步写法。

下面是一个mysql2Promise风格的简短示例,文件名可命名为code_02_pool.js:

const mysql = require('mysql2/promise');

const pool = mysql.createPool({
  host: process.env.DB_HOST,
  user: process.env.DB_USER,
  password: process.env.DB_PASSWORD,
  database: process.env.DB_NAME,
  waitForConnections: true,
  connectionLimit: 10
});

async function getCurrentTime() {
  const [rows] = await pool.query('SELECT NOW() AS CurrentTime');
  return rows[0].CurrentTime;
}

getCurrentTime()
  .then((time) => console.log(time))
  .catch((err) => console.error(err.message));

mysql2的pool.query()返回Promise,配合async/await可以减少回调嵌套。如果项目允许选择驱动,新项目直接使用mysql2是更省心的做法。

十、本节课程知识要点

  • Node.js连接MySQL需要安装第三方驱动,mysql与mysql2是常见选择。

  • 连接参数中的密码应通过环境变量注入,不要硬编码。

  • 使用?占位符传参,避免SQL注入。

  • 单连接用connection.end()关闭;高频请求场景用连接池。

  • 连接失败时优先检查用户权限、数据库是否存在、MySQL服务是否运行。

  • 新项目可优先考虑mysql2/promise,旧项目迁移成本较低。

十一、练习思考题

  1. 把app.js中的连接配置改为从.env文件读取,使用dotenv包加载。

  2. 在employees表中插入三条记录,分别查询薪资大于8000的记录和全部记录。

  3. 把单连接模式改为连接池模式,观察代码结构变化。

  4. 尝试用mysql2/promise重写插入与查询逻辑,对比回调写法的差异。

  5. 模拟密码错误、数据库不存在、MySQL未启动三种情况,记录终端输出并说明排查思路。

← MySQL 数据库 创建 MySQL →
分享笔记 (共有 篇笔记)
验证码:
微信公众号