MySQL 连接池 (Pool) 常用方法详解
MySQL 连接池 (Pool) 常用方法详解
1. 创建连接池
首先需要创建连接池实例:
const mysql = require('mysql2/promise'); // 使用Promise版本const pool = mysql.createPool({host: 'localhost',user: 'root',password: 'password',database: 'test',waitForConnections: true,connectionLimit: 10, // 最大连接数queueLimit: 0 // 无限制的排队请求
});
2. 核心方法
2.1 pool.query(sqlString, [values])
- 作用:执行SQL查询的最简单方法
- 特点:
- 自动获取和释放连接
- 支持参数化查询
- 返回值:
[rows, fields]
- 示例:
const [rows] = await pool.query('SELECT * FROM users WHERE age > ?', [18]);
2.2 pool.execute(sqlString, [values])
- 作用:执行预处理语句
- 特点:
- 比
query()
更高效(特别是重复查询) - 自动创建和缓存预处理语句
- 比
- 返回值:
[rows, fields]
- 示例:
const [rows] = await pool.execute('SELECT * FROM products WHERE price > ?', [100]);
2.3 pool.getConnection()
- 作用:显式获取一个连接
- 使用场景:
- 需要执行事务
- 需要执行多个相关查询
- 注意:必须手动释放连接
- 示例:
const connection = await pool.getConnection();
try {// 使用connection执行查询
} finally {connection.release(); // 必须释放
}
3. 连接对象(Connection)方法
通过getConnection()
获取的连接对象有以下方法:
3.1 connection.query()
- 同
pool.query()
,但在特定连接上执行
3.2 connection.execute()
- 同
pool.execute()
,但在特定连接上执行
3.3 connection.beginTransaction()
- 作用:开始事务
- 示例:
await connection.beginTransaction();
3.4 connection.commit()
- 作用:提交事务
- 示例:
await connection.commit();
3.5 connection.rollback()
- 作用:回滚事务
- 示例:
await connection.rollback();
3.6 connection.release()
- 作用:释放连接回连接池
- 重要:必须调用,否则会导致连接泄漏
4. 连接池管理方法
4.1 pool.end()
- 作用:优雅关闭连接池
- 示例:
await pool.end(); // 关闭所有连接
4.2 pool.escape(value)
- 作用:手动转义值
- 示例:
const name = pool.escape(userInput); // 防止SQL注入
4.3 pool.escapeId(identifier)
- 作用:转义标识符(表名、列名)
- 示例:
const tableName = pool.escapeId('user table');
5. 事务处理完整示例
const connection = await pool.getConnection();
try {await connection.beginTransaction();// 执行多个操作await connection.query('UPDATE accounts SET balance = balance - ? WHERE id = ?', [100, 1]);await connection.query('UPDATE accounts SET balance = balance + ? WHERE id = ?', [100, 2]);await connection.commit();
} catch (err) {await connection.rollback();throw err;
} finally {connection.release();
}
6. 事件监听
连接池可以监听以下事件:
6.1 'acquire'
- 当从池中获取连接时触发
pool.on('acquire', (connection) => {console.log('Connection %d acquired', connection.threadId);
});
6.2 'release'
- 当连接释放回池中时触发
pool.on('release', (connection) => {console.log('Connection %d released', connection.threadId);
});
6.3 'enqueue'
- 当查询需要等待可用连接时触发
pool.on('enqueue', () => {console.log('Waiting for available connection slot');
});
7. 最佳实践
- 总是使用参数化查询防止SQL注入
- 及时释放连接避免连接泄漏
- 合理设置连接池大小根据应用负载调整
- 事务中使用try-catch确保正确处理错误
- 考虑使用ORM如Sequelize、TypeORM简化复杂操作
8. 性能提示
- 对于高频查询,使用
execute()
比query()
更高效 - 批量操作考虑使用连接池的单个连接
- 长时间不用的连接池应该调用
end()
关闭
这些方法涵盖了MySQL连接池的绝大多数使用场景,合理使用可以构建高效可靠的数据库应用。