MySQL: Node.js连接MySQL实战开发
最后更新:2026-08-26
前端开发者学后端,Node.js + MySQL 是最佳起点。
本课讲解用 Node.js 操作 MySQL。
graph TB
A[Node.js 应用] --> B[mysql2 驱动]
B --> C[连接池]
C --> D[获取连接]
D --> E[参数化查询]
E --> F{操作类型}
F -->|查询| G[execute SELECT]
F -->|插入| H[execute INSERT]
F -->|更新| I[execute UPDATE]
F -->|删除| J[execute DELETE]
F -->|事务| K[beginTransaction]
K --> L[commit / rollback]
D --> M[释放连接回池]
1. 你将学到
- mysql2 驱动安装与连接
- 连接池配置
- CRUD 操作
- 参数化查询(防 SQL 注入)
- 事务封装
2. 一个真实的故事
(1) 痛点:学完SQL却不会在项目中用
前端开发者学完了 SQL,但用 Node.js 写后端时一脸茫然:手写 SQL 字符串拼接容易被注入,连接管理混乱导致数据库连接耗尽,异步回调嵌套让代码难以维护。
(2) mysql2+连接池+参数化查询的解法
用 mysql2 驱动(支持 Promise)、连接池管理连接、参数化查询防注入。
| 维度 | 手动拼接SQL | mysql2+连接池 |
|---|---|---|
| SQL注入风险 | 极高 | 零(参数化查询) |
| 连接管理 | 混乱(可能耗尽) | 自动管理(池化复用) |
| 代码风格 | 回调地狱 | async/await |
| 生产就绪 | ❌ | ✅ |
3. 安装与连接
▶ 示例:安装 mysql2
BASH
npm install mysql2
▶ 示例:创建连接
JAVASCRIPT
const mysql = require('mysql2/promise');
async function main() {
const connection = await mysql.createConnection({
host: 'localhost',
user: 'root',
password: 'Root123!',
database: 'mydb'
});
const [rows] = await connection.execute('SELECT VERSION()');
console.log(rows);
await connection.end();
}
main();
4. 连接池
JAVASCRIPT
const pool = mysql.createPool({
host: 'localhost',
user: 'root',
password: 'Root123!',
database: 'mydb',
waitForConnections: true,
connectionLimit: 10,
queueLimit: 0
});
// 使用连接池查询
const [rows] = await pool.execute('SELECT * FROM users WHERE id = ?', [1]);
5. CRUD 操作
▶ 示例:查询数据
JAVASCRIPT
// 查询所有用户
const [users] = await pool.execute('SELECT * FROM users');
// 条件查询
const [user] = await pool.execute(
'SELECT * FROM users WHERE id = ?',
[userId]
);
▶ 示例:插入数据
JAVASCRIPT
const [result] = await pool.execute(
'INSERT INTO users (username, email) VALUES (?, ?)',
['alice', 'alice@email.com']
);
console.log(result.insertId);
▶ 示例:更新数据
JAVASCRIPT
const [result] = await pool.execute(
'UPDATE users SET email = ? WHERE id = ?',
['new@email.com', 1]
);
console.log(result.affectedRows);
▶ 示例:删除数据
JAVASCRIPT
const [result] = await pool.execute(
'DELETE FROM users WHERE id = ?',
[1]
);
console.log(result.affectedRows);
6. 防止 SQL 注入
(1) 错误:字符串拼接
JAVASCRIPT
// 危险!SQL 注入
const sql = `SELECT * FROM users WHERE username = '${username}'`;
(2) 正确:参数化查询
JAVASCRIPT
// 安全:参数化查询
const [rows] = await pool.execute(
'SELECT * FROM users WHERE username = ?',
[username]
);
7. 事务封装
JAVASCRIPT
async function transfer(fromId, toId, amount) {
const conn = await pool.getConnection();
try {
await conn.beginTransaction();
await conn.execute(
'UPDATE accounts SET balance = balance - ? WHERE id = ?',
[amount, fromId]
);
await conn.execute(
'UPDATE accounts SET balance = balance + ? WHERE id = ?',
[amount, toId]
);
await conn.commit();
return { success: true };
} catch (error) {
await conn.rollback();
return { success: false, error: error.message };
} finally {
conn.release();
}
}
8. ORM 简介
| ORM | 说明 |
|---|---|
| Sequelize | 老牌 ORM,功能全 |
| Prisma | 新一代,类型安全 |
| TypeORM | TypeScript 支持好 |
| Knex.js | 查询构建器 |
JAVASCRIPT
// Prisma 示例
const users = await prisma.user.findMany({
where: { status: 'active' },
include: { orders: true }
});
❓ 常见问题
Q 用 mysql 还是 mysql2?
A 推荐 mysql2(支持 Promise、性能更好)。
Q 连接池大小设多少?
A 一般 10-20,根据并发量调整。
Q 什么时候用 ORM?
A 复杂项目用 ORM 简化开发,简单项目用原生 SQL 更灵活。
Q mysql 和 mysql2 区别?
A mysql 是旧驱动只支持回调,mysql2 支持 Promise+性能更好,推荐 mysql2。
Q 连接池大小设多少?
A 公式为 CPU核心数×2+磁盘数,普通 Web 应用 10-20 即可。
📖 小节
- mysql2 是 Node.js 的 MySQL 驱动,支持 Promise
- 连接池复用连接,提升性能
- 参数化查询防止 SQL 注入
- 事务保证数据一致性
- ORM 简化数据库操作
📝 作业
-
基础题(难度⭐):用 Node.js 连接 MySQL,查询并打印用户列表。
-
进阶题(难度⭐⭐):实现完整的 CRUD API(增删改查)。
-
挑战题(难度⭐⭐⭐):实现转账功能,包含事务和错误处理。