mysql2 连接 MySQL 的基本写法
直接用
mysql2建立连接,比老版
mysql库更推荐——它原生支持 Promise、批量查询、流式读取,且默认启用连接池。
最简连接示例(不带错误处理):
const mysql = require('mysql2/promise');
<p>const connection = await mysql.createConnection({
host: 'localhost',
user: 'root',
password: '123456',
database: 'test_db',
port: 3306
});</p><p>const [rows] = await connection.execute('SELECT * FROM users WHERE id = ?', [1]);注意:
mysql2/promise是开启 Promise 支持的入口;若用
require('mysql2'),得手动包装成 Promise 或用回调。
为什么 execute() 比 query() 更安全
execute()自动做 SQL 参数化,彻底避免拼接字符串导致的注入风险;
query()虽也支持占位符,但容易误用字符串拼接。
execute('SELECT * FROM t WHERE id = ?', [id]) ✅ 安全,参数被强制转义
query('SELECT * FROM t WHERE id = ' + id) ❌ 危险,id 若为 "1 OR 1=1"就炸了
query('SELECT * FROM t WHERE name = ?', [name]) ✅ 可行,但不如 execute语义明确
另外,
execute()返回的是
[rows, fields]数组解构,
fields包含列元信息,调试时很有用。
连接池怎么配才不崩
生产环境别用单连接,要用
createPool。常见崩点是没设
waitForConnections和
queueLimit,高并发下直接拒绝请求。
const pool = mysql.createPool({
host: 'localhost',
user: 'root',
password: '123456',
database: 'test_db',
waitForConnections: true,
connectionLimit: 10,
queueLimit: 0 // 0 表示不限队列长度,避免抛 ECONNREFUSED
});关键参数说明:
connectionLimit:最大活跃连接数,一般设为数据库 max_connections 的 70% 左右
waitForConnections:设 false 时,连接池满会立刻报
PoolClosedError;设 true 才排队
queueLimit:设 0 表示无限排队;设正整数(如 100)则超限直接 reject
acquireTimeout:获取连接超时毫秒,默认 10s,可按业务调低(比如 3000)
事务里怎么正确 rollback
用
beginTransaction()+
commit()/
rollback()时,必须确保所有分支都覆盖异常处理,否则连接可能卡在事务中不释放。
const connection = await pool.getConnection();
try {
await connection.beginTransaction();
await connection.execute('INSERT INTO orders (...) VALUES (?)', [...]);
await connection.execute('UPDATE stock SET count = count - 1 WHERE id = ?', [sid]);
await connection.commit();
} catch (err) {
await connection.rollback(); // 必须写!且不能只 catch 不 rollback
throw err;
} finally {
connection.release(); // 记得归还连接,不然池子迟早耗尽
}容易漏的点:
忘记connection.release()→ 连接泄漏,池子逐渐枯竭 在
catch里没调
rollback()→ 事务挂起,锁表或阻塞其他操作 用
pool.execute()执行事务?不行,事务必须复用同一个
connection
事务必须绑定到一个具体连接上,不能靠池子自动分发。
