nodejs使用async/await同步操作mysql

注: 教程基于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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末笛辟,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子序苏,更是在濱河造成了極大的恐慌手幢,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,919評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件忱详,死亡現(xiàn)場離奇詭異围来,居然都是意外死亡,警方通過查閱死者的電腦和手機匈睁,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,567評論 3 392
  • 文/潘曉璐 我一進店門监透,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人航唆,你說我怎么就攤上這事胀蛮。” “怎么了糯钙?”我有些...
    開封第一講書人閱讀 163,316評論 0 353
  • 文/不壞的土叔 我叫張陵粪狼,是天一觀的道長。 經(jīng)常有香客問我任岸,道長再榄,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,294評論 1 292
  • 正文 為了忘掉前任演闭,我火速辦了婚禮不跟,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘米碰。我一直安慰自己,他們只是感情好购城,可當我...
    茶點故事閱讀 67,318評論 6 390
  • 文/花漫 我一把揭開白布吕座。 她就那樣靜靜地躺著,像睡著了一般瘪板。 火紅的嫁衣襯著肌膚如雪吴趴。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,245評論 1 299
  • 那天侮攀,我揣著相機與錄音锣枝,去河邊找鬼。 笑死兰英,一個胖子當著我的面吹牛撇叁,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播畦贸,決...
    沈念sama閱讀 40,120評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼陨闹,長吁一口氣:“原來是場噩夢啊……” “哼楞捂!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起趋厉,我...
    開封第一講書人閱讀 38,964評論 0 275
  • 序言:老撾萬榮一對情侶失蹤寨闹,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后君账,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體繁堡,經(jīng)...
    沈念sama閱讀 45,376評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,592評論 2 333
  • 正文 我和宋清朗相戀三年乡数,在試婚紗的時候發(fā)現(xiàn)自己被綠了帖蔓。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,764評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡瞳脓,死狀恐怖塑娇,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情劫侧,我是刑警寧澤埋酬,帶...
    沈念sama閱讀 35,460評論 5 344
  • 正文 年R本政府宣布,位于F島的核電站烧栋,受9級特大地震影響写妥,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜审姓,卻給世界環(huán)境...
    茶點故事閱讀 41,070評論 3 327
  • 文/蒙蒙 一珍特、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧魔吐,春花似錦扎筒、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,697評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至辞色,卻和暖如春骨宠,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背相满。 一陣腳步聲響...
    開封第一講書人閱讀 32,846評論 1 269
  • 我被黑心中介騙來泰國打工层亿, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人立美。 一個月前我還...
    沈念sama閱讀 47,819評論 2 370
  • 正文 我出身青樓匿又,卻偏偏與公主長得像,于是被迫代替她去往敵國和親悯辙。 傳聞我的和親對象是個殘疾皇子琳省,可洞房花燭夜當晚...
    茶點故事閱讀 44,665評論 2 354

推薦閱讀更多精彩內(nèi)容