nodejs使用async/await同步操作mysql

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

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容