注: 教程基于koa2 node.js版本需要>=7.6, 當然同樣適用于express,因為async/await是JavaScript的ESnext的新特性
Node.js的核心概念是非阻塞IO和異步編程。雖然這種機制給Node.js帶來了巨大的優勢和好處,但同時它也帶來了許多問題和挑戰,比如我們在做一些異步操作的時候,如果需要拿到異步操作返回的結果之后再進行下一步操作,通常需要通過一層層的異步回調,導致維護十分困難,代碼可讀性差,koa2天生就支持async特性,當然目前在express也可以使用。
安裝 mysql驅動
mysql文檔地址 當然在此之前你必須先安裝并啟動mysql
npm install mysql --save
創建mysql連接
const mysql = require('mysql')
const connection = mysql.createConnection({
host : '127.0.0.1', // 數據庫地址
user : 'root', // 數據庫用戶
password : '123456' // 數據庫密碼
database : 'my_database' // 選中數據庫
})
// 連接數據庫 這一步不是必須的 因為在query的時候會默認連接
connection.connect((err) => {
// 如果在這一步拋出錯誤 請檢查數據庫配置 比如權限 選中數據庫是否存在等等..
if (err) return console.log('數據庫連接失敗', err.message);
console.log('數據庫連接成功');
})
// 執行sql腳本對數據庫進行讀寫
connection.query('SELECT * FROM my_table', (error, results, fields) => {
if (error) throw error
// connected!
// 結束會話
connection.release()
});
注意:一個事件就有一個從開始到結束的過程,數據庫會話操作執行完后,就需要關閉掉,以免占用連接資源。
創建數據連接池
一般情況下,我們不會按照上面的做法,因為一般操作數據庫是很復雜的讀寫過程,不只是一個會話,如果直接用會話操作,就需要每次會話都要配置連接參數,所以這時候就需要連接池管理會話(如果使用MongoDB則無需擔心這些問題mongo會管理自己的連接集合,或連接"池")
const mysql = require('mysql')
// 創建數據池
const pool = mysql.createPool({
host : '127.0.0.1', // 數據庫地址
user : 'root', // 數據庫用戶
password : '123456' // 數據庫密碼
database : 'my_database' // 選中數據庫
})
// 在數據池中進行會話操作
pool.getConnection(function(err, connection) {
connection.query('SELECT * FROM my_table', (error, results, fields) => {
// 結束會話
connection.release();
// 如果有錯誤就拋出
if (error) throw error;
})
})
封裝mysql請求
前面內容作為前置知識,由于mysql模塊的操作都是異步操作,每次操作的結果都是在回調函數中執行,現在有了async/await,就可以用同步的寫法去操作數據庫
對于async/await不熟悉的朋友請先查閱相關文檔以了解用法,不過沒熟悉也沒關系,記住async/await 需要返回一個 Promise 對象就可以了.
const mysql = require('mysql')
const pool = mysql.createPool({
host : '127.0.0.1',
user : 'root',
password : '123456',
database : 'my_database'
})
// 接收一個sql語句 以及所需的values
// 這里接收第二參數values的原因是可以使用mysql的占位符 '?'
// 比如 query(`select * from my_database where id = ?`, [1])
let query = function( sql, values ) {
// 返回一個 Promise
return new Promise(( resolve, reject ) => {
pool.getConnection(function(err, connection) {
if (err) {
reject( err )
} else {
connection.query(sql, values, ( err, rows) => {
if ( err ) {
reject( err )
} else {
resolve( rows )
}
// 結束會話
connection.release()
})
}
})
})
}
module.exports = query
簡單的我們就封裝好了,這個時候我們可以這么使用
koa2
router.post('/login', async (ctx) => {
// 這里可以同步獲取到rows
let rows = await query('select * from im_user')
ctx.body = {
code: 0,
msg: '請求成功',
data: rows
}
})
express
router.post('/login', async (req, res) => {
// 原來做法
// query('select * from im_user', (err, rows) => {
// res.json({
// code: 0,
// msg: '請求成功',
// data: rows
// })
// })
// 現在
const rows = await query('select * from im_user')
res.json({
code: 0,
msg: '請求成功',
data: rows
})
})
當然 如果你覺得把sql語句散落在各個地方不太好,你可以統一管理.
源碼地址 koa-gachat