Node.js 连接 MySQL:从零开始构建数据库交互能力
你有没有想过,为什么很多网站能实时显示用户信息、订单状态或文章评论?背后的关键之一,就是数据库的支撑。而 Node.js 作为现代后端开发的主流选择,与 MySQL 的结合,正是构建动态网站的基石。
今天我们就来聊聊如何用 Node.js 连接 MySQL 数据库。别担心,即使你是编程初学者,只要跟着一步步来,也能轻松掌握这项核心技能。我们不会讲太多理论,而是用真实代码和场景,带你从“连不上”到“稳稳地查数据”。
为什么选择 Node.js 与 MySQL 的组合?
在开始之前,先理解一下这对“黄金搭档”为什么受欢迎。
Node.js 是基于 Chrome V8 引擎的 JavaScript 运行环境,它最大的特点是“非阻塞 I/O”,这意味着它可以高效处理大量并发请求,特别适合 Web 服务、API 接口等场景。
而 MySQL 是最流行的开源关系型数据库之一,结构清晰、稳定可靠,适合存储用户数据、商品信息、日志记录等结构化内容。
把它们放在一起,就像把“高速路”(Node.js)和“仓库”(MySQL)连接起来:前端发来的请求,通过 Node.js 快速处理,然后去 MySQL 仓库里找数据,再返回给用户。整个过程流畅又高效。
安装 MySQL 与准备数据库环境
在写代码之前,你得先有一个 MySQL 数据库可用。如果你还没装,可以按以下步骤操作。
安装 MySQL 服务(以 macOS 为例)
打开终端,执行以下命令:
brew install mysql
brew services start mysql
注意:如果你用的是 Windows 或 Linux,建议使用官方安装包或包管理器(如 apt、yum)安装 MySQL 服务。
登录 MySQL 并创建数据库
安装完成后,进入 MySQL 命令行:
mysql -u root -p
输入密码后,进入数据库命令行界面。接下来创建一个名为 myapp 的数据库:
-- 创建数据库
CREATE DATABASE myapp CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- 使用该数据库
USE myapp;
-- 创建一个用户表
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(50) NOT NULL,
email VARCHAR(100) UNIQUE NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
✅ 小贴士:
utf8mb4是 MySQL 中支持 emoji 的编码,推荐使用。AUTO_INCREMENT表示自增主键,就像给每条记录分配一个唯一的“身份证号”。
使用 npm 安装 MySQL 驱动
Node.js 本身不支持直接连接 MySQL,需要借助第三方驱动。最常用的驱动是 mysql2,它比旧版 mysql 更快、更稳定。
在项目根目录下,初始化项目并安装驱动:
npm init -y
npm install mysql2
📌 为什么用
mysql2?它支持 Promise、流式读取、预编译语句等现代特性,代码更简洁,性能更好。
编写连接代码:Node.js 连接 MySQL 的第一步
现在我们来写一段代码,实现 Node.js 与 MySQL 的连接。
创建一个文件 db.js,内容如下:
// db.js
const mysql = require('mysql2');
// 创建连接池(推荐方式,提高性能)
const pool = mysql.createPool({
host: 'localhost', // 数据库地址
user: 'root', // 用户名
password: 'your_password', // 替换为你的实际密码
database: 'myapp', // 要连接的数据库名
port: 3306, // MySQL 默认端口
waitForConnections: true, // 是否等待连接
connectionLimit: 10, // 最大连接数
queueLimit: 0 // 连接队列限制,0 表示无限制
});
// 将 pool 转为 Promise 风格,方便使用 async/await
const promisePool = pool.promise();
// 导出连接池对象,供其他模块使用
module.exports = promisePool;
📝 注释说明:
createPool创建连接池,避免频繁创建/销毁连接,提升性能。promise()方法将回调风格转为 Promise 风格,让代码更清晰。password请替换为你自己的 MySQL 密码,别写死在代码里,生产环境建议用环境变量。
实际操作:插入与查询数据
现在连接已建立,我们来尝试插入和查询数据。
创建一个 user.js 文件,实现用户管理功能:
// user.js
const db = require('./db');
// 添加新用户
async function createUser(name, email) {
try {
// 使用 SQL 插入语句,参数用 ? 占位符,防止 SQL 注入
const [result] = await db.execute(
'INSERT INTO users (name, email) VALUES (?, ?)',
[name, email]
);
console.log('用户创建成功,ID:', result.insertId);
return result.insertId;
} catch (err) {
console.error('插入失败:', err.message);
throw err;
}
}
// 查询所有用户
async function getAllUsers() {
try {
const [rows] = await db.execute('SELECT id, name, email, created_at FROM users');
console.log('所有用户:', rows);
return rows;
} catch (err) {
console.error('查询失败:', err.message);
throw err;
}
}
// 按 ID 查询用户
async function getUserById(id) {
try {
const [rows] = await db.execute(
'SELECT id, name, email, created_at FROM users WHERE id = ?',
[id]
);
if (rows.length === 0) {
console.log('未找到用户');
return null;
}
console.log('找到用户:', rows[0]);
return rows[0];
} catch (err) {
console.error('查询失败:', err.message);
throw err;
}
}
// 导出函数
module.exports = { createUser, getAllUsers, getUserById };
🔍 重点说明:
- 使用
?占位符是安全做法,能有效防止 SQL 注入攻击。await db.execute()返回的是一个数组,第一个元素是结果,第二个是元数据。rows.length === 0是判断查询结果为空的常见写法。
运行测试:验证连接是否成功
创建 index.js 文件,作为入口文件:
// index.js
const { createUser, getAllUsers, getUserById } = require('./user');
async function main() {
try {
// 插入两个测试用户
await createUser('张三', 'zhangsan@example.com');
await createUser('李四', 'lisi@example.com');
// 查询所有用户
const users = await getAllUsers();
// 查询单个用户
const user = await getUserById(1);
console.log('✅ 所有操作完成,Node.js 连接 MySQL 成功!');
} catch (err) {
console.error('❌ 运行出错:', err.message);
}
}
main();
在终端运行:
node index.js
如果看到类似输出:
用户创建成功,ID: 1
用户创建成功,ID: 2
所有用户: [ { id: 1, name: '张三', email: 'zhangsan@example.com', created_at: 2025-04-05T10:00:00.000Z }, ... ]
找到用户: { id: 1, name: '张三', email: 'zhangsan@example.com', created_at: 2025-04-05T10:00:00.000Z }
✅ 所有操作完成,Node.js 连接 MySQL 成功!
恭喜你,已经成功实现了 Node.js 连接 MySQL 的完整流程!
常见问题与最佳实践
在实际项目中,我们常会遇到一些问题。下面列出几个关键点:
1. 连接超时或拒绝连接?
- 检查 MySQL 是否正在运行:
brew services list | grep mysql - 检查
host是否正确(localhost 或 127.0.0.1) - 确认用户名和密码无误(注意区分大小写)
2. 如何避免密码明文暴露?
使用 .env 文件管理敏感信息。安装 dotenv:
npm install dotenv
创建 .env 文件:
DB_HOST=localhost
DB_USER=root
DB_PASSWORD=your_secure_password
DB_NAME=myapp
修改 db.js:
require('dotenv').config();
const pool = mysql.createPool({
host: process.env.DB_HOST,
user: process.env.DB_USER,
password: process.env.DB_PASSWORD,
database: process.env.DB_NAME,
port: 3306,
waitForConnections: true,
connectionLimit: 10,
queueLimit: 0
});
✅ 这样做更安全,也方便多环境部署。
3. 使用事务处理多步操作
当需要“要么全成功,要么全失败”时,比如转账,就要用事务:
async function transferMoney(fromId, toId, amount) {
const connection = await db.getConnection();
try {
await connection.beginTransaction();
// 扣款
await connection.execute(
'UPDATE users SET balance = balance - ? WHERE id = ?',
[amount, fromId]
);
// 加款
await connection.execute(
'UPDATE users SET balance = balance + ? WHERE id = ?',
[amount, toId]
);
await connection.commit();
console.log('转账成功');
} catch (err) {
await connection.rollback();
console.error('转账失败,已回滚:', err.message);
throw err;
} finally {
connection.release();
}
}
🧠 事务就像“银行转账”:两笔操作必须同时成功,否则全部撤销。
结语
今天我们从零开始,一步步完成了 Node.js 连接 MySQL 的全过程:环境搭建、驱动安装、连接配置、数据操作,再到生产级优化建议。
你已经掌握了这项核心技能,接下来可以尝试:
- 用 Express 搭建 REST API
- 将数据返回给前端(如 Vue 3.0、React)
- 实现用户登录、注册功能
Node.js 连接 MySQL 不是“高阶技巧”,而是每个全栈开发者都该掌握的基础能力。只要动手实践,你也能写出稳定、高效的后端服务。
别停下脚步,下一站,就是你的第一个完整项目!