Sequelize

MySQL

model

  1. 'use strict';
  2. const moment = require('moment');// 日期处理模块
  3. module.exports = app => {
  4. const Instance = app.model.define('test', {
  5. id: {
  6. /**
  7. * ! 数据类型
  8. * ?
  9. * STRING 字符串
  10. *
  11. * DOUBLE 0 1 double
  12. *
  13. * *&*********日期
  14. * DATE DATETIME 适用于 mysql / sqlite, 带时区的TIMESTAMP 适用于 postgres
  15. * DATE(6) DATETIME(6) 适用于 mysql 5.6.4+. 支持6位精度的小数秒
  16. * DATEONLY 不带时间的 DATE
  17. *
  18. * *&*********数字
  19. * INTEGER integer
  20. * FLOAT float
  21. * REAL real
  22. * DOUBLE double
  23. *
  24. */
  25. type: app.Sequelize.INTEGER(5),
  26. primaryKey: true, // 住建
  27. autoIncrement: true, // 自增
  28. unique: true, // 唯一
  29. allowNull: true, // 不允许为空
  30. description: '唯一标识', // 描述
  31. defaultValue: 10000, // 默认值
  32. // comment: '这是带有注释的列', //额外的注释
  33. },
  34. // 日期的默认值 => 当前时间
  35. // myDate: { type: DataTypes.DATE, defaultValue: DataTypes.NOW },
  36. // 创建时间 修改时间 格式化
  37. createdAt: { type: app.Sequelize.DATE, get() { return moment(this.getDataValue('created_at')).format('YYYY-MM-DD HH:mm:ss'); } },
  38. updatedAt: { type: app.Sequelize.DATE, get() { return moment(this.getDataValue('updated_at')).format('YYYY-MM-DD HH:mm:ss'); } },
  39. }, {
  40. // comment: '实例', // 表注释
  41. // modelName: 'tablename', // 定义表名
  42. // 在上面的属性中使用 `unique: true` 与在模型的参数中创建索引完全相同:
  43. indexes: [
  44. {
  45. unique: true,
  46. fields: [ 'id' ], // 唯一约束
  47. },
  48. ],
  49. });
  50. // 外键约束
  51. Instance.associate = function() {
  52. // 一对一
  53. // app.model.Stores.Type.belongsTo(app.model.Managers.User, { foreignKey: 'author', targetKey: 'id' });
  54. // 一对多
  55. // app.model.Answer.Content.hasMany(app.model.Answer.Options, { foreignKey: 'answerId', targetKey: 'id' });
  56. // app.model.Answer.Options.belongsTo(app.model.Answer.Content, { foreignKey: 'answerId', targetKey: 'id' });
  57. };
  58. return Instance;
  59. };

controller

  1. 'use strict';
  2. const Controller = require('egg').Controller;
  3. const Sequelize = require('sequelize');
  4. const Op = Sequelize.Op;
  5. // 全局变量
  6. const tableName = 'TableName';
  7. // 数据库模块 名称
  8. const models = {
  9. modelGroup: 'ModelGroup',
  10. modelName: 'ModelName',
  11. };
  12. // 定义创建接口的请求参数规则
  13. const createRule = {
  14. // username: {
  15. // type: 'userName', // type -属性的类型,每种类型都有自己的验证规则。
  16. // 如果required设置为false,则此属性可以为null或未定义。默认为true
  17. // convertType-使参数转换的输入参数的具体类型,支持int,number,string和boolean,还支持功能,定制自己的转换方法。
  18. // default-属性的默认值,一旦允许该属性为非必需和丢失的,则参数将使用该默认值。这可能会更改原始的输入参数。
  19. // },
  20. };
  21. // 定义修改接口的请求参数规则
  22. const updateRule = {
  23. // id: { type: 'Id' },
  24. };
  25. class TestController extends Controller {
  26. /**
  27. * @description 查询数据
  28. */
  29. async index() {
  30. // 分页参数
  31. const pagedata = {
  32. page: this.ctx.query.page,
  33. limit: this.ctx.query.rows,
  34. };
  35. const pageNumber = this.ctx.helper.pageNumber(pagedata);
  36. const search = this.ctx.query.search || ''; // 搜索内容
  37. const find = await this.ctx.service.database.query.findAndCountAll({
  38. ...models,
  39. // 查询条件
  40. conditions: {
  41. ...pageNumber,
  42. attributes: {
  43. // 排除 查询字段
  44. exclude: [ 'updated_at', 'deleted_at', 'created_at' ],
  45. include: [
  46. // 字段 修改名称
  47. [ Sequelize.col('created_at'), 'createdTime' ],
  48. ],
  49. },
  50. order: [ // id倒叙
  51. [ 'id', 'DESC' ],
  52. ],
  53. include: [
  54. // 关联 表
  55. ],
  56. // 查询 条件
  57. // WHERE
  58. where: {
  59. name: { // TODO
  60. [Op.like]: `%${search}%`,
  61. // [Op.and]: {a: 5} // 且 (a = 5)
  62. // [Op.or]: [{a: 5}, {a: 6}] // (a = 5 或 a = 6)
  63. // [Op.gt]: 6, // id > 6
  64. // [Op.gte]: 6, // id >= 6
  65. // [Op.lt]: 10, // id < 10
  66. // [Op.lte]: 10, // id <= 10
  67. // [Op.ne]: 20, // id != 20
  68. // [Op.eq]: 3, // = 3
  69. // [Op.not]: true, // 不是 TRUE
  70. // [Op.between]: [6, 10], // 在 6 和 10 之间
  71. // [Op.notBetween]: [11, 15], // 不在 11 和 15 之间
  72. // [Op.in]: [1, 2], // 在 [1, 2] 之中
  73. // [Op.notIn]: [1, 2], // 不在 [1, 2] 之中
  74. // [Op.like]: '%hat', // 包含 '%hat'
  75. // [Op.notLike]: '%hat' // 不包含 '%hat'
  76. // [Op.iLike]: '%hat' // 包含 '%hat' (不区分大小写) (仅限 PG)
  77. // [Op.notILike]: '%hat' // 不包含 '%hat' (仅限 PG)
  78. // [Op.startsWith]: 'hat' // 类似 'hat%'
  79. // [Op.endsWith]: 'hat' // 类似 '%hat'
  80. // [Op.substring]: 'hat' // 类似 '%hat%'
  81. // [Op.regexp]: '^[h|a|t]' // 匹配正则表达式/~ '^[h|a|t]' (仅限 MySQL/PG)
  82. // [Op.notRegexp]: '^[h|a|t]' // 不匹配正则表达式/!~ '^[h|a|t]' (仅限 MySQL/PG)
  83. // [Op.iRegexp]: '^[h|a|t]' // ~* '^[h|a|t]' (仅限 PG)
  84. // [Op.notIRegexp]: '^[h|a|t]' // !~* '^[h|a|t]' (仅限 PG)
  85. // [Op.like]: { [Op.any]: ['cat', 'hat']} // 包含任何数组['cat', 'hat'] - 同样适用于 iLike 和 notLike
  86. // [Op.overlap]: [1, 2] // && [1, 2] (PG数组重叠运算符)
  87. // [Op.contains]: [1, 2] // @> [1, 2] (PG数组包含运算符)
  88. // [Op.contained]: [1, 2] // <@ [1, 2] (PG数组包含于运算符)
  89. // [Op.any]: [2,3] // 任何数组[2, 3]::INTEGER (仅限PG)
  90. // [Op.col]: 'user.organization_id' // = 'user'.'organization_id', 使用数据库语言特定的列标识符, 本例使用 PG
  91. },
  92. },
  93. },
  94. });
  95. this.ctx.body = await this.ctx.helper.outputJSON({ data: { ...find }, msg: `${tableName}信息成功` });
  96. }
  97. /**
  98. * @description 创建数据
  99. */
  100. async create() {
  101. const data = this.ctx.request.body;
  102. data.author = await this.ctx.managers.id;
  103. this.ctx.validate(createRule, this.ctx.request.body);
  104. const creat = await this.ctx.service.database.create.create({
  105. ...models,
  106. data,
  107. });
  108. this.ctx.body = await this.ctx.helper.outputJSON({ data: creat, msg: `${tableName}创建成功` });
  109. }
  110. /**
  111. * @description 更新数据
  112. */
  113. async update() {
  114. try {
  115. this.ctx.validate(updateRule, this.ctx.request.body);
  116. const retdata = await this.ctx.service.database.update.update({
  117. ...models,
  118. data: {
  119. // TODO 修改字段
  120. // TODO UPDATA
  121. // name: this.ctx.request.body.name,
  122. },
  123. id: this.ctx.helper.parseInt(this.ctx.params.id),
  124. });
  125. const res = retdata ? await this.ctx.helper.outputJSON({ msg: `${tableName}信息修改` }) : await this.ctx.helper.outputErrJSON({ msg: '没有找到修改的内容' });
  126. this.ctx.body = await res;
  127. return;
  128. } catch (error) {
  129. this.ctx.body = await this.ctx.helper.outputErrJSON({ msg: '出现错误' });
  130. return;
  131. }
  132. }
  133. /**
  134. * @description 删除数据
  135. */
  136. async destroy() {
  137. const data = await this.ctx.service.database.query.findByPk({ id: this.ctx.helper.parseInt(this.ctx.params.id), ...models });
  138. if (!data) {
  139. this.ctx.body = await this.ctx.helper.outputErrJSON({ msg: '没有找到要删除的内容' });
  140. return;
  141. }
  142. await this.service.database.destroy.destroy({ id: this.ctx.helper.parseInt(this.ctx.params.id), ...models });
  143. this.ctx.body = await this.ctx.helper.outputJSON({ msg: `${tableName}已删除` });
  144. }
  145. }
  146. module.exports = TestController;

sequelizerc

文档

安装

  1. npm install --save-dev sequelize-cli

配置

  1. // .sequelizerc
  2. 'use strict';
  3. const path = require('path');
  4. module.exports = {
  5. config: path.join(__dirname, 'database/config.json'),
  6. 'migrations-path': path.join(__dirname, 'database/migrations'),
  7. 'seeders-path': path.join(__dirname, 'database/seeders'),
  8. 'models-path': path.join(__dirname, 'app/model'),
  9. };

初始化 Migrations 配置文件和目录

  1. npx sequelize init:config
  2. npx sequelize init:migrations
  3. npx sequelize init
  1. ### 迁移
  2. (文档)[https://github.com/demopark/sequelize-docs-Zh-CN/blob/v5/migrations.md]
  3. 1. 安装 sequelize-cli
  4. npm install --save-dev sequelize-cli
  5. 2. .sequelizerc 配置文件
  6. ``` .sequelizerc
  7. 'use strict';
  8. const path = require('path');
  9. module.exports = {
  10. config: path.join(__dirname, 'database/config.json'),
  11. 'migrations-path': path.join(__dirname, 'database/migrations'),
  12. 'seeders-path': path.join(__dirname, 'database/seeders'),
  13. 'models-path': path.join(__dirname, 'app/model'),
  14. };
  1. 初始化 Migrations 配置文件和目录

npx sequelize init:config npx sequelize init:migrations npx sequelize init

  1. config, 包含配置文件,它告诉CLI如何连接数据库
  2. models,包含你的项目的所有模型
  3. migrations, 包含所有迁移文件
  4. seeders, 包含所有种子文件
  1. 将其改成我们项目中使用的数据库配置
  1. "development": {
  2. "username": "root",
  3. "password": null,
  4. "database": "egg-sequelize-doc-default", // 数据库
  5. "host": "127.0.0.1", // 地址
  6. "dialect": "mysql" // 数据库类型
  7. },
  1. 此时 sequelize-cli 和相关的配置也都初始化好了,我们可以开始编写项目的第一个 Migration 文件来创建我们的一个 users 表了 npx sequelize migration:generate —name=init-users

npx sequelize migration:generate —name User —attributes firstName:string,lastName:string,email:string

如果你的数据库还不存在,你可以调用 db:create 命令. 通过正确的访问,它将为你创建该数据库.

  1. 添加字段
  1. 'use strict';
  2. module.exports = {
  3. // 在执行数据库升级时调用的函数,创建 users 表
  4. up: async (queryInterface, Sequelize) => {
  5. const { INTEGER, DATE, STRING } = Sequelize;
  6. await queryInterface.createTable('users', {
  7. id: { type: INTEGER, primaryKey: true, autoIncrement: true },
  8. name: STRING(30),
  9. age: INTEGER,
  10. created_at: DATE,
  11. updated_at: DATE,
  12. });
  13. },
  14. // 在执行数据库降级时调用的函数,删除 users 表
  15. down: async queryInterface => {
  16. await queryInterface.dropTable('users');
  17. },
  18. };
  1. 执行 migrate 进行数据库变更 ```

    升级数据库

    npx sequelize db:migrate

    如果有问题需要回滚,可以通过 db:migrate:undo 回退一个变更

    npx sequelize db:migrate:undo

    可以通过 db:migrate:undo:all 回退到初始状态

    npx sequelize db:migrate:undo:all

  1. 8. 编写model
  2. ``` js
  3. 'use strict';
  4. module.exports = app => {
  5. const { STRING, INTEGER, DATE } = app.Sequelize;
  6. const User = app.model.define('user', {
  7. id: { type: INTEGER, primaryKey: true, autoIncrement: true },
  8. name: STRING(30),
  9. age: INTEGER,
  10. created_at: DATE,
  11. updated_at: DATE,
  12. });
  13. return User;
  14. };
  1. 访问model
  1. // app/controller/users.js
  2. const Controller = require('egg').Controller;
  3. function toInt(str) {
  4. if (typeof str === 'number') return str;
  5. if (!str) return str;
  6. return parseInt(str, 10) || 0;
  7. }
  8. class UserController extends Controller {
  9. async index() {
  10. const ctx = this.ctx;
  11. const query = { limit: toInt(ctx.query.limit), offset: toInt(ctx.query.offset) };
  12. ctx.body = await ctx.model.User.findAll(query);
  13. }
  14. async show() {
  15. const ctx = this.ctx;
  16. ctx.body = await ctx.model.User.findByPk(toInt(ctx.params.id));
  17. }
  18. async create() {
  19. const ctx = this.ctx;
  20. const { name, age } = ctx.request.body;
  21. const user = await ctx.model.User.create({ name, age });
  22. ctx.status = 201;
  23. ctx.body = user;
  24. }
  25. async update() {
  26. const ctx = this.ctx;
  27. const id = toInt(ctx.params.id);
  28. const user = await ctx.model.User.findByPk(id);
  29. if (!user) {
  30. ctx.status = 404;
  31. return;
  32. }
  33. const { name, age } = ctx.request.body;
  34. await user.update({ name, age });
  35. ctx.body = user;
  36. }
  37. async destroy() {
  38. const ctx = this.ctx;
  39. const id = toInt(ctx.params.id);
  40. const user = await ctx.model.User.findByPk(id);
  41. if (!user) {
  42. ctx.status = 404;
  43. return;
  44. }
  45. await user.destroy();
  46. ctx.status = 200;
  47. }
  48. }
  49. module.exports = UserController;
  1. 创建第一个种子
  1. npx sequelize-cli seed:generate --name managers
  2. # 同上
  3. npx sequelize seed:generate --name managers
  1. 运行种子 撤销种子
  1. # 运行种子
  2. npx sequelize-cli db:seed:all
  3. # 如果你想撤消最近的种子
  4. npx sequelize-cli db:seed:undo
  5. # 如果你想撤消特定的种子
  6. npx sequelize-cli db:seed:undo --seed name-of-seed-as-in-data
  7. # 如果你想撤消所有的种子
  8. npx sequelize-cli db:seed:undo:all

下一个是具有外键的迁移示例. 你可以使用 references 来指定外键:

  1. module.exports = {
  2. up: (queryInterface, Sequelize) => {
  3. return queryInterface.createTable('Person', {
  4. name: Sequelize.STRING,
  5. isBetaMember: {
  6. type: Sequelize.BOOLEAN,
  7. defaultValue: false,
  8. allowNull: false
  9. },
  10. userId: {
  11. type: Sequelize.INTEGER,
  12. references: {
  13. model: {
  14. tableName: 'users',
  15. schema: 'schema'
  16. }
  17. key: 'id'
  18. },
  19. allowNull: false
  20. },
  21. });
  22. },
  23. down: (queryInterface, Sequelize) => {
  24. return queryInterface.dropTable('Person');
  25. }
  26. }

.sequelizerc 文件

这是一个特殊的配置文件. 它允许你指定通常作为参数传递给CLI的各种选项:

env: 在其中运行命令的环境 config: 配置文件的路径 options-path: 带有其他参数的 JSON 文件的路径 migrations-path: migrations 文件夹的路径 seeders-path: seeders 文件夹的路径 models-path: models 文件夹的路径 url: 要使用的数据库连接字符串. 替代使用 —config 文件 debug: 可用时显示各种调试信息

初始化项目

  1. # 创建数据库
  2. npx sequelize db:create
  3. # 创建表
  4. npx sequelize db:migrate
  5. # 创建默认值
  6. npx sequelize db:seed:all

数据回滚

  1. # 如果你想撤消所有的种子
  2. npx sequelize-cli db:seed:undo:all
  3. # 回退到初始状态
  4. npx sequelize db:migrate:undo:all

生成公钥:openssl genrsa -out rsa_private_key.pem 1024 生成私钥: openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem

```

mongoose

egg-mongoose GitHub地址