资讯专栏INFORMATION COLUMN

koa访问mysql数据库操作

hufeng / 365人阅读

摘要:首先我要完成的是对数据库操作的封装,将以前项目实践中的代码迁移到上来,于是决定先完成一起学中的任务。小结框架以库为核心组织,很好的用来解决了回调函数问题。进行接口形式包装的时候,要注意回调函数要完全符合其要求的形式

契机

用restify与express有一年多了,一直在考虑什么时候上koa与es6,看到《一起学koa》项目,决定以此为契机行动起来。首先我要完成的是对数据库操作的封装,将以前项目实践中的代码迁移到koa上来,于是决定先完成《一起学koa》中的mysql任务。

koa基本知识

koa依赖co,最新版基于promise实现。我们使用koa的时候都是通过use添加一个中间件,router也是一个个中间件,我们看一下use都做了什么?

app.use = function(fn){
  this.middleware.push(fn);
  return this;
};

它只是将参数保存起来,然后返回引用,最后由co完成调用,因此要求中间件中的异步调用都使用Promise形式。

实现方法一(co-mysql)

mysql库是以回调形式实现的,而koa中间件要求Promise形式,经过搜索,发现了co-mysql和mysql-co,这两个库的思路差不多,mysql-co封装度更高,并使用速度更快的mysql2,而co-mysql更简单,只是将mysql.query封装成Promise形式。下面是基于co-mysql的写法

var wrapper = require("co-mysql"),
  mysql = require("mysql");
var options = {
    host : "localhost",
    port : 3306 ,
    database : "test",
    user: "root",
    password : "rootroot"
};

var pool = mysql.createPool(options),
  p = wrapper(pool);

...
  var rows = yield p.query("SELECT 1");
  yield this.render("index", {
        title: rows[0].fieldName
    });
...
})();
实现方法二(promisify-node)

找到promisify-node库,可以将库整体转化为Promise形式,示例代码如下:

var promisify = require("promisify-node");
var db = promisify("myDbHelper");
...
var rows = yield db.getById("tableName", {id:1});
    yield this.render("index", {
        title: rows[0].fieldName
    });
...
实现方法三(thunkify、thunkify-wrap)

看tj/co说明的Yieldables部分说明如下:
The yieldable objects currently supported are:

promises

thunks (functions)

array (parallel execution)

objects (parallel execution)

generators (delegation)

generator functions (delegation)

因此使用thunkify也能够完成封装,thunkify-wrap是一个增强版的thunkify,不过看说明,这种方法在未来的发展中可能会被淘汰,大概的使用如下:

var genify = require("thunkify-wrap").genify;
var db = genify("myDbHelper");
...
var rows = yield db.getById("tableName", {id:1});
    yield this.render("index", {
        title: rows[0].fieldName
    });
...
实现方法四(直接方法)

直接改造原来express下的代码为Promise形式,参考了co-mysql,并仔细学习了Promise相关知识,完成了已有代码的改造,代码及说明如下:
dbHelper.js

var config = require("./dbconfig");

var options = {
    "host": config.db_host,
    "port": config.db_port,
    "database": config.db_name,
    "user": config.db_user,
    "password": config.db_passwd
}

var mysql = require("mysql");
var pool = mysql.createPool(options);

//内部对mysql的封装,执行sql语句
function execQuery(sql, values, callback) {
    var errinfo;
    pool.getConnection(function(err, connection) {
        if (err) {
            errinfo = "DB-获取数据库连接异常!";
            throw errinfo;
        } else {
            var querys = connection.query(sql, values, function(err, rows) {
                release(connection);
                if (err) {
                    errinfo = "DB-SQL语句执行错误:" + err;
                    callback(err);
                } else {
                    callback(null,rows);        //注意:第一个参数必须为null
                }
            });
        }
    });
}

function release(connection) {
    try {
        connection.release(function(error) {
            if (error) {
                console.log("DB-关闭数据库连接异常!");
            }
        });
    } catch (err) {}
}
//对外接口返回Promise函数形式
exports.getById = function(tablename, id){
    return new Promise(function(resolve, reject){
        var values = {id:id};
        var sql = "select * from ?? where ?";
        execQuery(sql,[tablename, values], function(err, rows){
            if(err){
                reject(err);
            }else{
                resolve(rows);
            }
        })
    });
}

routes/index.js

var db = require("../dbHelper");
...
var rows = yield db.getById("tableName", {id:1});
    yield this.render("index", {
        title: rows[0].fieldName
    });
...
代码

请参考这个项目中的数据库操作部分,项目处于持续开发中,数据库示例部分取自该项目。

https://github.com/zhoutk/koadmin.git
小结

koa框架以co库为核心组织,很好的用generator来解决了回调函数问题。进行Promise接口形式包装的时候,要注意:回调函数要完全符合其要求的形式:

function(err, rows){
            if(err){
                reject(err);
            }else{
                resolve(rows);
            }
        })

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/46577.html

相关文章

  • Node.js项目中操作MySQL

    摘要:初始化项目创建项目目录,并使用初始化项目后,执行下面操作安装依赖创建填写你的填写你的用户名填写你的密码在中执行,当看到中打印出,表明数据库连接成功。打开浏览器访问,当看到屏幕显示时,表名项目初始化成功。 showImg(https://segmentfault.com/img/remote/1460000016835739?w=1053&h=586); 本文是一篇使用mysql这个np...

    derek_334892 评论0 收藏0
  • 记一次 React + Koa + Mysql 构建个人博客

    摘要:前言由于一直在用写业务,为了熟悉下开发模式,所以选择了。数据库一开始用的是,后来换成了,一套下来感觉也挺好上手的。 前言 由于一直在用 vue 写业务,为了熟悉下 react 开发模式,所以选择了 react。数据库一开始用的是 mongodb,后来换成 mysql 了,一套下来感觉 mysql 也挺好上手的。react-router、koa、mysql 都是从0开始接触开发的,期间遇...

    darkbug 评论0 收藏0
  • 全栈前端入门必看 koa2+mysql+vue+vant 构建简单版移动端博客

    摘要:要注意这里必须和创建的时候传入的一致,因为服务端需要用创建时的来解密。是校验码解析时需要一致才能取到信息过期时间设置为格式有。 koa2+mysql+vue+vant 构建简单版移动端博客 具体内容展示 showImg(https://segmentfault.com/img/remote/1460000015962704?w=375&h=670); showImg(https://s...

    luckyw 评论0 收藏0
  • 全栈前端入门必看 koa2+mysql+vue+vant 构建简单版移动端博客

    摘要:要注意这里必须和创建的时候传入的一致,因为服务端需要用创建时的来解密。是校验码解析时需要一致才能取到信息过期时间设置为格式有。 koa2+mysql+vue+vant 构建简单版移动端博客 具体内容展示 showImg(https://segmentfault.com/img/remote/1460000015962704?w=375&h=670); showImg(https://s...

    maybe_009 评论0 收藏0
  • 全栈前端入门必看 koa2+mysql+vue+vant 构建简单版移动端博客

    摘要:要注意这里必须和创建的时候传入的一致,因为服务端需要用创建时的来解密。是校验码解析时需要一致才能取到信息过期时间设置为格式有。 koa2+mysql+vue+vant 构建简单版移动端博客 具体内容展示 showImg(https://segmentfault.com/img/remote/1460000015962704?w=375&h=670); showImg(https://s...

    Galence 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<