注: 教程基于koa2 node.js版本需要>=7.6, 當然同樣適用于express蚁袭,因為async/await是JavaScript的ESnext的新特性
Node.js的核心概念是非阻塞IO和異步編程征懈。雖然這種機制給Node.js帶來了巨大的優(yōu)勢和好處,但同時它也帶來了許多問題和挑戰(zhàn)揩悄,比如我們在做一些異步操作的時候卖哎,如果需要拿到異步操作返回的結(jié)果之后再進行下一步操作,通常需要通過一層層的異步回調(diào)删性,導致維護十分困難亏娜,代碼可讀性差,koa2天生就支持async特性蹬挺,當然目前在express也可以使用维贺。
安裝 mysql驅(qū)動
mysql文檔地址 當然在此之前你必須先安裝并啟動mysql
npm install mysql --save
創(chuàng)建mysql連接
const mysql = require('mysql')
const connection = mysql.createConnection({
host : '127.0.0.1', // 數(shù)據(jù)庫地址
user : 'root', // 數(shù)據(jù)庫用戶
password : '123456' // 數(shù)據(jù)庫密碼
database : 'my_database' // 選中數(shù)據(jù)庫
})
// 連接數(shù)據(jù)庫 這一步不是必須的 因為在query的時候會默認連接
connection.connect((err) => {
// 如果在這一步拋出錯誤 請檢查數(shù)據(jù)庫配置 比如權(quán)限 選中數(shù)據(jù)庫是否存在等等..
if (err) return console.log('數(shù)據(jù)庫連接失敗', err.message);
console.log('數(shù)據(jù)庫連接成功');
})
// 執(zhí)行sql腳本對數(shù)據(jù)庫進行讀寫
connection.query('SELECT * FROM my_table', (error, results, fields) => {
if (error) throw error
// connected!
// 結(jié)束會話
connection.release()
});
注意:一個事件就有一個從開始到結(jié)束的過程,數(shù)據(jù)庫會話操作執(zhí)行完后巴帮,就需要關(guān)閉掉溯泣,以免占用連接資源。
創(chuàng)建數(shù)據(jù)連接池
一般情況下榕茧,我們不會按照上面的做法垃沦,因為一般操作數(shù)據(jù)庫是很復雜的讀寫過程,不只是一個會話用押,如果直接用會話操作肢簿,就需要每次會話都要配置連接參數(shù),所以這時候就需要連接池管理會話(如果使用MongoDB則無需擔心這些問題mongo會管理自己的連接集合只恨,或連接"池")
const mysql = require('mysql')
// 創(chuàng)建數(shù)據(jù)池
const pool = mysql.createPool({
host : '127.0.0.1', // 數(shù)據(jù)庫地址
user : 'root', // 數(shù)據(jù)庫用戶
password : '123456' // 數(shù)據(jù)庫密碼
database : 'my_database' // 選中數(shù)據(jù)庫
})
// 在數(shù)據(jù)池中進行會話操作
pool.getConnection(function(err, connection) {
connection.query('SELECT * FROM my_table', (error, results, fields) => {
// 結(jié)束會話
connection.release();
// 如果有錯誤就拋出
if (error) throw error;
})
})
封裝mysql請求
前面內(nèi)容作為前置知識译仗,由于mysql模塊的操作都是異步操作,每次操作的結(jié)果都是在回調(diào)函數(shù)中執(zhí)行官觅,現(xiàn)在有了async/await纵菌,就可以用同步的寫法去操作數(shù)據(jù)庫
對于async/await不熟悉的朋友請先查閱相關(guān)文檔以了解用法,不過沒熟悉也沒關(guān)系休涤,記住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
// 這里接收第二參數(shù)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 )
}
// 結(jié)束會話
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
// })
// })
// 現(xiàn)在
const rows = await query('select * from im_user')
res.json({
code: 0,
msg: '請求成功',
data: rows
})
})
當然 如果你覺得把sql語句散落在各個地方不太好咱圆,你可以統(tǒng)一管理.
源碼地址 koa-gachat