NodeJs数据库

nodejs使用async/await同步操作mysql

Node.js的核心概念是非阻塞IO和异步编程。虽然这种机制给Node.js带来了巨大的优势和好处,但同时它也带来了许多问题和挑战,比如我们在做一些异步操作的时候,如果需要拿到异步操作返回的结果之后再进行下一步操作,通常需要通过一层层的异步回调,导致维护十分困难,代码可读性差,koa2天生就支持async特性,当然目前在express也可以使用。

安装 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

简单的我们就封装好了,这个时候我们可以这么使用

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语句散落在各个地方不太好,你可以统一管理.