nodejs使用async/await同步操作mysql

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
    //     })
    // })

//.then
// router.get('/list', async (req, res, next) => {
//     let sql = 'select * from userinfo'
//     await db.query(sql).then(result => {
//         if (result && result.length > 0) {
//             let val = result[0]
//             res.json({
//                 ...Tips[0],
//                 data: val
//             })
//         } else {
//             res.json({
//                 ...Tips[1003]
//             })
//         }
//     }).catch(e => {
//         res.json({
//             ...Tips[1002]
//         })
//     })
// })
    
    // 现在
    const rows = await query('select * from im_user')
    res.json({
        code: 0,
        msg: '请求成功',
        data: rows
    })
    
})

当然 如果你觉得把sql语句散落在各个地方不太好,你可以统一管理.

源码地址 koa-gachat

转载 https://www.jianshu.com/p/142f2231355e

  • 4
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是封装nodejs使用mysql2的连接池的写法: ```javascript const mysql = require('mysql2/promise'); class MysqlPool { constructor(config) { this.pool = mysql.createPool(config); } async execute(sql, values) { const connection = await this.pool.getConnection(); try { const [rows] = await connection.execute(sql, values); return rows; } catch (err) { throw err; } finally { connection.release(); } } async beginTransaction() { const connection = await this.pool.getConnection(); try { await connection.beginTransaction(); return connection; } catch (err) { connection.release(); throw err; } } async commitTransaction(connection) { try { await connection.commit(); connection.release(); } catch (err) { await connection.rollback(); connection.release(); throw err; } } async rollbackTransaction(connection) { try { await connection.rollback(); connection.release(); } catch (err) { connection.release(); throw err; } } } module.exports = MysqlPool; ``` 在上面的代码中,我们使用了 `mysql2/promise` 模块创建了一个连接池,然后封装了一些常用的方法,包括 `execute`、 `beginTransaction`、 `commitTransaction` 和 `rollbackTransaction`。其中,`execute` 方法用于执行 SQL 语句,`beginTransaction` 方法用于开启事务,`commitTransaction` 方法用于提交事务,`rollbackTransaction` 方法用于回滚事务。 使用时,只需要实例化 `MysqlPool` 类,然后调用相应的方法即可。例如: ```javascript const MysqlPool = require('./mysql-pool'); const config = { host: 'localhost', user: 'root', password: '123456', database: 'test', waitForConnections: true, connectionLimit: 10, queueLimit: 0, }; const pool = new MysqlPool(config); async function getUsers() { const sql = 'SELECT * FROM users'; const result = await pool.execute(sql); return result; } getUsers().then((result) => { console.log(result); }).catch((err) => { console.error(err); }); ``` 上面的代码中,我们首先创建了一个 `config` 对象,包含了数据库连接的配置信息。然后实例化了一个 `MysqlPool` 对象,并且调用了 `execute` 方法执行了一条 SQL 查询语句。最后输出查询结果或者错误信息。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值