用egg搭建后端管理服务端

初始化

javascript 复制代码
mkdir egg-example && cd egg-example
npm init egg --type=simple
yarn

启动项目

javascript 复制代码
yarn dev 
open http://localhost:7001

安装 Sequelize

1、安装对应的插件

javascript 复制代码
yarn add egg-sequelize mysql2

2、开启插件

javascript 复制代码
// config/plugin.js
module.exports = {
  // had enabled by egg
  static: {
    enable: true
  },
  // 数据库
  sequelize: {
    enable: true,
    package: "egg-sequelize"
  }
};

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

javascript 复制代码
  // sequelize 配置
  config.sequelize = {
    dialect: "mysql", // 数据路类型-我用的是mysql
    host: "127.0.0.1", // 数据库地址
    port: 3306, // 数据库端口号
    database: "egg-sequelize", // 数据库名称
    username: "root", // 用户名
    password: "123456", // 密码
    // 配置数据库时间为东八区北京时间
    timezone: "+08:00",
    define: {
      freezeTableName: true // 强制表名称等于模型名称
    }
  }

安装 sequelize-cli

javascript 复制代码
yarn add sequelize-cli --dev

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

javascript 复制代码
'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 配置文件和目录

javascript 复制代码
npx sequelize init:config
npx sequelize init:migrations

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

javascript 复制代码
{
  "development": {
    "username": "root",
    "password": null,
    "database": "database_development",
    "host": "127.0.0.1",
    "dialect": "mysql"
  },
  "test": {
    "username": "root",
    "password": null,
    "database": "database_test",
    "host": "127.0.0.1",
    "dialect": "mysql"
  },
  "production": {
    "username": "root",
    "password": null,
    "database": "database_production",
    "host": "127.0.0.1",
    "dialect": "mysql"
  }
}

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

javascript 复制代码
npx sequelize migration:generate --name=init-users

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

javascript 复制代码
'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 进行数据库变更

javascript 复制代码
# 升级数据库
# 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:

javascript 复制代码
'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:

javascript 复制代码
// 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 挂载到路由上:

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

自动生成 model 文件

javascript 复制代码
yarn add egg-sequelize-auto --dev

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

javascript 复制代码
"scripts": {
   "dbload": "egg-sequelize-auto -o ./app/model -h localhost -p 3306 -d database -u username -x password"
}
相关推荐
Mr Xu_41 分钟前
告别硬编码:前端项目中配置驱动的实战优化指南
前端·javascript·数据结构
Byron07071 小时前
从 0 到 1 搭建 Vue 前端工程化体系:提效、提质、降本实战落地
前端·javascript·vue.js
zhengfei6111 小时前
【AI平台】- 基于大模型的知识库与知识图谱智能体开发平台
vue.js·语言模型·langchain·知识图谱·多分类
徐小夕@趣谈前端1 小时前
Web文档的“Office时刻“:jitword共建版2.0发布!让浏览器变成本地生产力
前端·数据结构·vue.js·算法·开源·编辑器·es6
德育处主任Pro2 小时前
纯前端网格路径规划:PathFinding.js的使用方法
开发语言·前端·javascript
墨笔.丹青2 小时前
基于QtQuick开发界面设计出简易的HarmonyUI界面----下
开发语言·前端·javascript
董世昌412 小时前
深度解析浅拷贝与深拷贝:底层逻辑、实现方式及实战避坑
前端·javascript·vue.js
扶苏10022 小时前
vue使用event.dataTransfer实现A容器数据拖拽复制到到B容器
前端·vue.js·chrome
David凉宸2 小时前
Vue 3 项目的性能优化策略:从原理到实践
前端·vue.js·性能优化
小马_xiaoen2 小时前
Proxy 与 Reflect 从入门到实战:ES6 元编程核心特性详解
前端·javascript·ecmascript·es6