简单的数据库操作通过使用egg-mysql 插件基本上可以满足需求,而在一些较为复杂的应用中,我们可能会需要一个 ORM 框架来帮助我们管理数据层的代码。sequelize 是一个广泛使用的 ORM 框架,支持多种数据库。
1.安装和配置插件
npm install --save egg-sequelize mysql2
在 config/plugin.ts 中引入 egg-sequelize 插件
在 config/config.default.ts 中编写 sequelize 配置
2.初始化数据库和 Migrations
我们可以直接通过 mysql 命令将表直接建好,但是这并不是一个对多人协作非常友好的开发模式。在项目的演进过程中,每一个迭代都有可能对数据库数据结构做变更,怎样跟踪每一个迭代的数据变更,并在不同的环境(开发、测试、CI)和迭代切换中,快速变更数据结构呢?这时候我们就需要 Migrations 来帮我们管理数据结构的变更了。
sequelize 提供了 sequelize-cli 工具来实现 Migrations,我们也可以在 egg 项目中引入 sequelize-cli。
1)安装 sequelize-cli
npm install --save-dev sequelize-cli
在 egg 项目中,我们希望将所有数据库 Migrations 相关的内容都放在 database 目录下,所以我们在项目根目录下新建一个 .sequelizerc 配置文件:
2)初始化 Migrations 配置文件和目录
npx sequelize init:config
npx sequelize init:migrations
3)执行完后会生成 database/config.json 文件和 database/migrations 目录,我们修改一下 database/config.json 中的内容,将其改成我们项目中使用的数据库配置:
此时 sequelize-cli 和相关的配置也都初始化好了,我们可以开始编写项目的第一个 Migration 文件来创建我们的一个 users 表了。
npx sequelize migration:generate --name=init-users
执行完后会在 database/migrations 目录下生成一个 migration 文件(${timestamp}-init-users.js),我们修改它来处理初始化 users 表:
4)执行 migrate 进行数据库变更
# 升级数据库 npx sequelize db:migrate
# 回滚数据库 npx sequelize db:migrate:undo
# 回退到初始状态 npx sequelize db:migrate:undo:all
执行之后,我们的数据库初始化就完成了。
3.编写代码
1)现在终于可以开始编写代码实现业务逻辑了,首先我们来在 app/model/ 目录下编写 user 这个 Model:
2)这个 Model 就可以在 Controller 和 Service 中通过 app.model.User 或者 ctx.model.User 访问到了,例如我们编写 app/controller/users.js
3)最后我们将这个 controller 挂载到路由上
4.单元测试
在编写测试之前,由于在前面的 egg 配置中,我们将单元测试环境和开发环境指向了不同的数据库,因此需要通过 Migrations 来初始化测试数据库的数据结构:
NODE_ENV=test npx sequelize db:migrate:up
有数据库访问的单元测试直接写起来会特别繁琐,特别是很多接口我们需要创建一系列的数据才能进行,造测试数据是一个非常繁琐的过程。为了简化单测,我们可以通过 factory-girl 模块来快速创建测试数据。
1)安装 factory-girl 依赖
https://www.jianshu.com/p/dfd0ca700a36
npm install --save-dev factory-girl
2)定义 factory-girl 的数据模型到 test/factories.js 中
3)初始化文件 test/.setup.js,引入 factory,并确保测试执行完后清理数据,避免被影响。
4)接下来我们就可以开始编写真正的测试用例了:
5)最后,如果我们需要在 CI 中运行单元测试,需要确保在执行测试代码之前,执行一次 migrate 确保数据结构更新,例如我们在 package.json 中声明 scripts.ci 来在 CI 环境下执行单元测试:
"scripts": {NODE_ENV=test npx sequelize db:migrate && egg-bin cov"}