Sequelize 搭建 MVC 项目

首先在 koa-generator 搭建的项目基础上创建如下结构:

koaTest
├─bin
├─node_modules
├─public
├─routes
├─server
│  ├─config
│  ├─controllers
│  ├─modules
│  └─schema
└─views

安装相关依赖:

$ yarn add sequelize mysql mysql2

配置Sequelize的数据库链接

创建 server/config/db.js 该文件主要用来创建 mysql 的数据库连接的。

const Sequelize = require('sequelize');
const sequelize = new Sequelize('dbname','dbusername','password',{
    host:'localhost',
    dialect:'mysql',
    operatorsAliases:false,
    dialectOptions:{
        //字符集
        charset:'utf8mb4',
        supportBigNumbers: true,
        bigNumberStrings: true
    },
    pool:{
        max: 5,
        min: 0,
        acquire: 30000,
        idle: 10000
    },
    timezone: '+08:00'  //东八时区
});
module.exports = {
    sequelize
};

这些代码可以直接使用,只需要将代码中实例化Sequelie对象语句中的dbname更改为你的数据库名,dbusername更改为你的数据库用户名,passoword更改为你的数据库密码,其中数据库名和数据库用户名不能为空,密码可以为空,为空时则为空的字符串就可以了。

const sequelize = new Sequelize('test','root','root',{
  ...

创建数据表

在数据库中传进 article 表:

DROP TABLE IF EXISTS `article`;
CREATE TABLE `article` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `title` varchar(255) NOT NULL,
  `author` varchar(255) NOT NULL,
  `content` varchar(255) NOT NULL,
  `category` varchar(255) NOT NULL,
  `createdAt` datetime,
  `updatedAt` datetime,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;
SET FOREIGN_KEY_CHECKS = 1;

创建模型

以上是使用sql语句创建表的方式,我们看另一种借助 Sequelize 建表方式 (Sequelize不光是能自动建表,还能做数据库的管理);

server/schema/article.js

module.exports = function(sequelize, DataTypes){
    return sequelize.define('article', {
        id:{
            type: DataTypes.INTEGER,
            primaryKey: true,
            allowNull: true,
            autoIncrement: true
        },
        //文章标题
        title:{
            type: DataTypes.STRING,
            allowNull: false,
            field: 'title'
        },
        //作者
        author:{
            type: DataTypes.STRING,
            allowNull: false,
            field: 'author'
        },
        //内容
        content:{
            type: DataTypes.STRING,
            allowNull: false,
            field:'content'
        },
        //文章分类
        category:{
            type: DataTypes.STRING,
            allowNull: false,
            field: 'category'
        },
        // 创建时间
        createdAt:{
            type: DataTypes.DATE
        },
        // 更新时间
        updatedAt:{
            type: DataTypes.DATE
        }
    }, {
        /**
         * 如果为true,则表示名称和model相同,即 article
         * 如果为fasle,mysql创建的表名称会是复数,即 articles
         * 如果指定的表名称本身就是复数,则形式不变
         */
        freezeTableName: true
    });
}

创建模块

server/modules/article.js

// 引入mysql的配置文件
const db = require('../config/db');
// 引入sequelize对象
const Sequelize = db.sequelize;
// 引入数据表模型
const Article = Sequelize.import('../schema/article');
Article.sync({force: false}); //自动创建表
class ArticleModel {
    /**
     * 创建文章模型
     * @param data
     * @returns {Promise<*>}
     */
    static async createArticle(data){
        return await Article.create({
            title: data.title, //标题
            author: data.author,  //作者
            content: data.content,  //文章内容
            category: data.category //文章分类
        });
    }
    /**
     * 查询文章的详情
     * @param id 文章ID
     * @returns {Promise<Model>}
     */
    static async getArticleDetail(id){
        return await Article.findOne({
            where:{
                id
            }
        });
    }
}
module.exports = ArticleModel;

创建控制器

server/controllers/article.js

const ArticleModel = require("../modules/article");
class articleController {
    /**
     * 创建文章
     * @param ctx
     * @returns {Promise.<void>}
     */
    static async create(ctx){
        //接收客服端
        let req = ctx.request.body;
        if(req.title && req.author && req.content && req.category){
            try{
                //创建文章模型
                const ret = await ArticleModel.createArticle(req);
                //使用刚刚创建的文章ID查询文章详情,且返回文章详情信息
                const data = await ArticleModel.getArticleDetail(ret.id);
                ctx.response.status = 200;
                ctx.body = {
                    code: 200,
                    msg: '创建文章成功',
                    data
                }
            }catch(err){
                ctx.response.status = 412;
                ctx.body = {
                    code: 412,
                    msg: '创建文章失败',
                    data: err
                }
            }
        }else {
            ctx.response.status = 416;
            ctx.body = {
                code: 200,
                msg: '参数不齐全'
            }
        }
    }
    /**
     * 获取文章详情
     * @param ctx
     * @returns {Promise.<void>}
     */
    static async detail(ctx){
        let id = ctx.params.id;
        if(id){
            try{
                // 查询文章详情模型
                let data = await ArticleModel.getArticleDetail(id);
                ctx.response.status = 200;
                ctx.body = {
                    code: 200,
                    msg: '查询成功',
                    data
                }
            }catch(err){
                ctx.response.status = 412;
                ctx.body = {
                    code: 412,
                    msg: '查询失败',
                    data: err
                }
            }
        }else {
            ctx.response.status = 416;
            ctx.body = {
                code: 416,
                msg: '文章ID必须传'
            }
        }
    }
}
module.exports = articleController;

创建路由

routes/index.js

const Router = require('koa-router');
const ArtileController = require('../server/controllers/article');
const router = new Router({
  prefix: '/api/v1'
});
/**
 * 文章接口
 */
//创建文章
router.post('/article/create', ArtileController.create);
//获取文章详情
router.get('/article/:id', ArtileController.detail)
module.exports = router

至此, 已经可以访问接口了, 先开启服务 yarn start, 浏览器输入 http://localhost:3000/api/v1/article/1 即可看到结果:

参考资料

更多有关Sequelize的介绍参考我编写的另一本书:

Sequelize

MIT Licensed | Copyright © 2018-present 滇ICP备16006294号

Design by Quanzaiyu | Power by VuePress