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