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連接池的絕大多數使用場景,合理使用可以構建高效可靠的數據庫應用。