注: 教程基于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
网友评论