教你egg.js如何连接Sequelize
1、 首先确保你机器上已经安装好MySQL了1
sudo apt-get install mysql-server mysql-client
2、 然后用npm
初始化一个项目1
2
3mkdir sequelize-project && cd sequelize-project
npm init egg --type=simple
npm i
安装并配置 egg-sequelize 插件(它会辅助我们将定义好的 Model 对象加载到 app 和 ctx 上)和 mysql2 模块:1
npm install --save egg-sequelize mysql2
在config/plugin.js
中引入 egg-sequelize 插件1
2
3
4exports.sequelize = {
enable: true,
package: 'egg-sequelize',
};
在config/config.default.js
中编写 sequelize 配置1
2
3
4
5
6
7
8config.sequelize = {
dialect: 'mysql',
host: '127.0.0.1',
port: 3306,
database: 'egg-sequelize-doc-default',
username: "root",
password: "root",
};
3、初始化数据库和 Migrations
接下来我们先暂时离开 egg 项目的代码,设计和初始化一下我们的数据库。首先我们通过 mysql 命令在本地快速创建开发用到的 database:1
mysql -u root -e 'CREATE DATABASE IF NOT EXISTS `egg-sequelize-doc-default`;'
4、安装 sequelize-cli1
npm install --save-dev sequelize-cli
在 egg 项目中,我们希望将所有数据库 Migrations 相关的内容都放在database
目录下,所以我们在项目根目录下新建一个.sequelizerc
配置文件:1
2
3
4
5
6
7
8
9
10 ;
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 配置文件和目录1
2npx sequelize init:config
npx sequelize init:migrations
执行完后会生成database/config.json
文件和database/migrations
目录,我们修改一下database/config.json
中的内容,将其改成我们项目中使用的数据库配置:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16{
"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 表了。1
npx sequelize migration:generate --name=init-users
执行完后会在database/migrations
目录下生成一个 migration 文件(${timestamp}-init-users.js
),我们修改它来处理初始化users
表:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 ;
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 进行数据库变更1
2
3
4
5
6 升级数据库
npx sequelize db:migrate
如果有问题需要回滚,可以通过 `db:migrate:undo` 回退一个变更
npx sequelize db:migrate:undo
可以通过 `db:migrate:undo:all` 回退到初始状态
npx sequelize db:migrate:undo:all
执行之后,我们的数据库初始化就完成了。
5、编写代码
现在终于可以开始编写代码实现业务逻辑了,首先我们来在app/model/
目录下编写 user 这个 Model:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16// app/model/user.js
;
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
:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58// 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 挂载到路由上:1
2
3
4
5// app/router.js
module.exports = app => {
const { router, controller } = app;
router.resources('users', '/users', controller.users);
};
针对users
表的 CURD 操作的接口就开发完了。
如果出现了 csrf 安全验证的话,可以在config/config.default.js
加上如下代码关闭 csrf:1
2
3
4
5
6
7
8
9
10
11.
.
.
config.security = {
csrf: {
enable: false,
},
};
.
.
.