美文网首页node
Egg 使用 Sequelize

Egg 使用 Sequelize

作者: oYang_Mr | 来源:发表于2020-04-25 23:08 被阅读0次

    安装

    npm install --save egg-sequelize mysql2
    在 config/plugin.js 中引入 egg-sequelize 插件

    exports.sequelize = {
       enable: true,
       package: 'egg-sequelize',
    };
    
    // 注意如果有引用 module.exports 那么这里应该这样引入
    
    module.exports = {
       sequelize: {
          enable: true,
          package: 'egg-sequelize'
       }
    };
    

    在 config/config.default.js 中编写 sequelize 配置

    config.sequelize = {
       dialect: 'mysql',
       host: '127.0.0.1',
       port: 3306,
       database: 'egg-sequelize-doc-default',
       username: 'root',
       password: null,
       // 配置数据库时间为东八区北京时间
       timezone: '+08:00'
       define: {
          freezeTableName: true // 强制表名称等于模型名称
       }
    };
    

    初始化数据库和 Migrations

    安装 sequelize-cli

    npm install --save-dev sequelize-cli

    在 egg 项目中,我们希望将所有数据库 Migrations 相关的内容都放在 database 目录下,所以我们在项目根目录下新建一个 .sequelizerc 配置文件:

    'use strict';
    
    const path = require('path');
    
    module.exports = {
       config: path.join(__dirname, 'database/config.json'),
       'migrations-path': path.join(__dirname, 'database/migrations'),
       'seeders-path': path.join(__dirname, 'database/seeders'),
       'models-path': path.join(__dirname, 'app/model'),
    };
    

    初始化 Migrations 配置文件和目录

    npx sequelize init:config
    npx sequelize init:migrations
    

    执行完后会生成 database/config.json 文件和 database/migrations 目录,我们修改一下 database/config.json 中的内容,将其改成我们项目中使用的数据库配置:

    {
       "development": {
          "username": "root",
          "password": null,
          "database": "egg-sequelize-doc-default",
          "host": "127.0.0.1",
          "dialect": "mysql"
       },
       "test": {
          "username": "root",
          "password": null,
          "database": "egg-sequelize-doc-unittest",
          "host": "127.0.0.1",
          "dialect": "mysql"
       }
    }
    

    此时 sequelize-cli 和相关的配置也都初始化好了,我们可以开始编写项目的第一个 Migration 文件来创建我们的一个 users 表了。

    npx sequelize migration:generate --name=init-users
    

    执行完后会在 database/migrations 目录下生成一个 migration 文件(${timestamp}-init-users.js),我们修改它来处理初始化 users 表:

    'use strict';
    
    module.exports = {
       // 在执行数据库升级时调用的函数,创建 users 表
       up: async (queryInterface, Sequelize) => {
          const { INTEGER, DATE, STRING } = Sequelize;
          await queryInterface.createTable('users', {
             id: { type: INTEGER, primaryKey: true, autoIncrement: true },
             name: STRING(30),
             age: INTEGER,
             created_at: DATE,
             updated_at: DATE,
          });
       },
       // 在执行数据库降级时调用的函数,删除 users 表
       down: async queryInterface => {
          await queryInterface.dropTable('users');
       },
    };
    

    执行 migrate 进行数据库变更

    # 升级数据库
    # npx sequelize db:migrate
    # 如果有问题需要回滚,可以通过 `db:migrate:undo` 回退一个变更
    # npx sequelize db:migrate:undo
    # 可以通过 `db:migrate:undo:all` 回退到初始状态
    # npx sequelize db:migrate:undo:all
    

    执行之后,我们的数据库初始化就完成了。

    编写代码

    现在终于可以开始编写代码实现业务逻辑了,首先我们来在 app/model/ 目录下编写 user 这个 Model:

    'use strict';
    
    module.exports = app => {
       const { STRING, INTEGER, DATE } = app.Sequelize;
    
       const User = app.model.define('user', {
          id: { type: INTEGER, primaryKey: true, autoIncrement: true },
          name: STRING(30),
          age: INTEGER,
          created_at: DATE,
          updated_at: DATE,
       });
    
       return User;
    };
    

    这个 Model 就可以在 Controller 和 Service 中通过 app.model.User 或者 ctx.model.User 访问到了,例如我们编写 app/controller/users.js

    // app/controller/users.js
    const Controller = require('egg').Controller;
    
    function toInt(str) {
       if (typeof str === 'number') return str;
       if (!str) return str;
       return parseInt(str, 10) || 0;
    }
    
    class UserController extends Controller {
       async index() {
          const ctx = this.ctx;
          const query = { limit: toInt(ctx.query.limit), offset: toInt(ctx.query.offset) };
          ctx.body = await ctx.model.User.findAll(query);
       }
    
       async show() {
          const ctx = this.ctx;
          ctx.body = await ctx.model.User.findByPk(toInt(ctx.params.id));
       }
    
       async create() {
          const ctx = this.ctx;
          const { name, age } = ctx.request.body;
          const user = await ctx.model.User.create({ name, age });
          ctx.status = 201;
          ctx.body = user;
       }
    
       async update() {
          const ctx = this.ctx;
          const id = toInt(ctx.params.id);
          const user = await ctx.model.User.findByPk(id);
          if (!user) {
             ctx.status = 404;
             return;
          }
    
          const { name, age } = ctx.request.body;
          await user.update({ name, age });
          ctx.body = user;
       }
    
       async destroy() {
          const ctx = this.ctx;
          const id = toInt(ctx.params.id);
          const user = await ctx.model.User.findByPk(id);
          if (!user) {
             ctx.status = 404;
             return;
          }
    
          await user.destroy();
          ctx.status = 200;
       }
    }
    
    module.exports = UserController;
    

    最后我们将这个 controller 挂载到路由上:

    // app/router.js
    module.exports = app => {
       const { router, controller } = app;
       router.resources('users', '/users', controller.users);
    };
    

    针对 users 表的 CURD 操作的接口就开发完了

    自动生成 model 文件

    npm install egg-sequelize-auto --save-dev

    在 package.json 的 script 里面添加把数据库生成 model 的命令( -o 表示生成 models 的路径,-h 表示主机,-p 表示端口,-d 表示数据库, -u 表示用户名,-x 表示密码)

    "scripts": {
       "dbload": "egg-sequelize-auto -o ./app/model -h localhost -p 3344 -d database -u username -x password"
    }
    

    然后直接运行 npm run dbload ,就会生成相对应的 model 了

    相关文章

      网友评论

        本文标题:Egg 使用 Sequelize

        本文链接:https://www.haomeiwen.com/subject/wualwhtx.html