原文: http://zetcode.com/javascript/sequelize/

Sequelize 教程展示了如何使用 Sequelize ORM 在 JavaScript 中对数据库进行编程。

Sequelize

Sequelize 是 Node.js 的基于 Promise 的 ORM。 它可与 PostgreSQL,MySQL,SQLite 和 MSSQL 方言配合使用,并具有可靠的事务支持,关系,读取复制等功能。

对象关系映射(ORM)是一种从面向对象的语言访问关系数据库的技术。

在本教程中,我们使用 MySQL。

设置续集

我们初始化一个 Node 应用并安装 Sequelize 和 MySQL 适配器。

  1. $ nodejs -v
  2. v10.12.0

我们使用 Node 版本 10.12.0。

  1. $ npm init

我们启动一个新的 Node 应用。

  1. $ npm i sequelize
  2. $ nmp i mysql2

我们安装 Seqelize 和 MySQL 驱动程序。 有两个驱动程序可用:mysqlmysql2; 我们选择了后者。

Sequelize 认证

在第一个示例中,我们创建与 MySQL 数据库的连接。

authenticate.js

  1. const Sequelize = require('sequelize');
  2. const path = 'mysql://user12:12user@localhost:3306/testdb';
  3. const sequelize = new Sequelize(path, { operatorsAliases: false });
  4. sequelize.authenticate().then(() => {
  5. console.log('Connection established successfully.');
  6. }).catch(err => {
  7. console.error('Unable to connect to the database:', err);
  8. }).finally(() => {
  9. sequelize.close();
  10. });

该示例在连接到 MySQL 数据库时显示一条消息。

  1. const Sequelize = require('sequelize');

我们加载 Sequelize 模块。

  1. const path = 'mysql://user12:12user@localhost:3306/testdb';

这是 MySQL 连接路径。 它包含用户名,密码,主机名,数据库端口和数据库名称。

  1. const sequelize = new Sequelize(path, { operatorsAliases: false });

我们实例化 Sequelize。

  1. sequelize.authenticate().then(() => {
  2. console.log('Connection established successfully.');
  3. ...

authenticate()方法通过尝试向数据库进行认证来测试连接。 建立连接后,我们将打印一条消息。

  1. }).catch(err => {
  2. console.error('Unable to connect to the database:', err);
  3. ...

如果发生错误,我们将打印一条错误消息。

  1. }).finally(() => {
  2. sequelize.close();
  3. });

最后,我们关闭数据库连接。

  1. $ node authenticate.js
  2. Executing (default): SELECT 1+1 AS result
  3. Connection established successfully

这是输出。 输出也包括调试输出。

Sequelize 模型定义

Model代表数据库中的表。 此类的实例代表数据库行。 Sequelize 的define()方法定义了一个新模型。

define_model.js

  1. const Sequelize = require('sequelize');
  2. const path = 'mysql://user12:12user@localhost:3306/mydb';
  3. const sequelize = new Sequelize(path, {
  4. operatorsAliases: false
  5. });
  6. let Dummy = sequelize.define('dummy', {
  7. description: Sequelize.STRING
  8. });
  9. Dummy.sync().then(() => {
  10. console.log('New table created');
  11. }).finally(() => {
  12. sequelize.close();
  13. })

该示例创建一个简单的模型。 它将模型保存到数据库表中。

  1. let Dummy = sequelize.define('dummy', {
  2. description: Sequelize.STRING
  3. });

创建了一个新模型Dummy。 第一个参数是型号名称。 第二个参数由属性组成,这些属性是表列。 在我们的例子中,我们有一个列名description,它是String类型。

  1. Dummy.sync().then(() => {
  2. console.log('New table created');
  3. }).finally(() => {
  4. sequelize.close();
  5. })

sync()方法将模型同步到数据库。 实际上,它将创建一个新的dummies表。 (表名是复数的。)

  1. $ node model_define.js
  2. Executing (default): CREATE TABLE IF NOT EXISTS `dummies` (`id` INTEGER
  3. NOT NULL auto_increment , `description` VARCHAR(255),
  4. `createdAt` DATETIME NOT NULL, `updatedAt` DATETIME NOT NULL,
  5. PRIMARY KEY (`id`)) ENGINE=InnoDB;
  6. Executing (default): SHOW INDEX FROM `dummies`
  7. New table created

这是输出。 默认情况下,Sequelize 提供日志记录。 可以使用logging选项将其关闭。

  1. mysql> describe dummies;
  2. +-------------+--------------+------+-----+---------+----------------+
  3. | Field | Type | Null | Key | Default | Extra |
  4. +-------------+--------------+------+-----+---------+----------------+
  5. | id | int(11) | NO | PRI | NULL | auto_increment |
  6. | description | varchar(255) | YES | | NULL | |
  7. | createdAt | datetime | NO | | NULL | |
  8. | updatedAt | datetime | NO | | NULL | |
  9. +-------------+--------------+------+-----+---------+----------------+
  10. 4 rows in set (0.00 sec)

我们检查在 MySQL 中创建的表。 Sequelize 还创建了另外两个列:createdAtupdatedAt。 可以使用timestamps选项将其关闭。

Sequelize 删除表

drop()方法删除一个表。

drop_table.js

  1. const Sequelize = require('sequelize');
  2. const path = 'mysql://user12:12user@localhost:3306/mydb';
  3. const sequelize = new Sequelize(path, {
  4. operatorsAliases: false,
  5. logging: false
  6. });
  7. let Dummy = sequelize.define('dummy', {
  8. description: Sequelize.STRING
  9. });
  10. Dummy.drop().then(() => {
  11. console.log('table deleted');
  12. }).finally(() => {
  13. sequelize.close();
  14. });

该示例删除dummies表。

Sequelize 时间戳

Sequelize 自动为模型添加时间戳。 我们可以使用timestamps控制此行为。

timestamps.js

  1. const Sequelize = require('sequelize');
  2. const path = 'mysql://user12:12user@localhost:3306/mydb';
  3. const sequelize = new Sequelize(path, {
  4. operatorsAliases: false,
  5. logging: false,
  6. define: {
  7. timestamps: false
  8. }
  9. });
  10. let Dummy = sequelize.define('dummy', {
  11. description: Sequelize.STRING
  12. });
  13. sequelize.sync({force: true}).then(() => {
  14. Dummy.create({ description: 'test 1' }).then(() => {
  15. console.log('table created');
  16. }).finally(() => {
  17. sequelize.close();
  18. });
  19. });

该示例创建一个没有时间戳的表。

  1. const sequelize = new Sequelize(path, {
  2. operatorsAliases: false,
  3. logging: false,
  4. define: {
  5. timestamps: false
  6. }
  7. });

在这里,我们关闭时间戳记。

  1. mysql> describe dummies;
  2. +-------------+--------------+------+-----+---------+----------------+
  3. | Field | Type | Null | Key | Default | Extra |
  4. +-------------+--------------+------+-----+---------+----------------+
  5. | id | int(11) | NO | PRI | NULL | auto_increment |
  6. | description | varchar(255) | YES | | NULL | |
  7. +-------------+--------------+------+-----+---------+----------------+
  8. 2 rows in set (0.00 sec)

我们确认表中没有时间戳。

Sequelize 批量创建

bulkCreate()方法创建并批量插入多个实例。 该方法采用对象数组。

bulk_create_notes.js

  1. const Sequelize = require('sequelize');
  2. const path = 'mysql://user12:12user@localhost:3306/mydb';
  3. const sequelize = new Sequelize(path, {
  4. operatorsAliases: false,
  5. logging: false
  6. });
  7. let Note = sequelize.define('notes', {
  8. description: Sequelize.STRING
  9. });
  10. let notes = [
  11. { description: 'Tai chi in the morning' },
  12. { description: 'Visited friend' },
  13. { description: 'Went to cinema' },
  14. { description: 'Listened to music' },
  15. { description: 'Watched TV all day' },
  16. { description: 'Walked for a hour' },
  17. ];
  18. sequelize.sync({ force: true }).then(() => {
  19. Note.bulkCreate(notes, { validate: true }).then(() => {
  20. console.log('notes created');
  21. }).catch((err) => {
  22. console.log('failed to create notes');
  23. console.log(err);
  24. }).finally(() => {
  25. sequelize.close();
  26. });
  27. });

表格示例记录了几行。

  1. const sequelize = new Sequelize(path, {
  2. operatorsAliases: false,
  3. logging: false
  4. });

我们禁用日志记录。

  1. sequelize.sync({ force: true }).then(() => {

sqeuelize.syn()同步所有型号。 在force选项丢弃的表,如果它的创建之前就存在。

  1. Note.bulkCreate(notes, { validate: true }).then(() => {
  2. console.log('notes created');
  3. ...

bulkCreate()创建具有六行的表格。

  1. mysql> select * from notes;
  2. +----+------------------------+---------------------+---------------------+
  3. | id | description | createdAt | updatedAt |
  4. +----+------------------------+---------------------+---------------------+
  5. | 1 | Tai chi in the morning | 2018-10-21 14:34:28 | 2018-10-21 14:34:28 |
  6. | 2 | Visited friend | 2018-10-21 14:34:28 | 2018-10-21 14:34:28 |
  7. | 3 | Went to cinema | 2018-10-21 14:34:28 | 2018-10-21 14:34:28 |
  8. | 4 | Listened to music | 2018-10-21 14:34:28 | 2018-10-21 14:34:28 |
  9. | 5 | Watched TV all day | 2018-10-21 14:34:28 | 2018-10-21 14:34:28 |
  10. | 6 | Walked for a hour | 2018-10-21 14:34:28 | 2018-10-21 14:34:28 |
  11. +----+------------------------+---------------------+---------------------+
  12. 6 rows in set (0.00 sec)

这是在数据库中创建的表。

Sequelize build()save()

使用build()save()分两步或使用create()一步创建新行。

build_save.js

  1. const Sequelize = require('sequelize');
  2. const path = 'mysql://user12:12user@localhost:3306/mydb';
  3. const sequelize = new Sequelize(path, {
  4. operatorsAliases: false,
  5. logging: false
  6. });
  7. let Note = sequelize.define('notes', {
  8. description: Sequelize.STRING
  9. });
  10. const note = Note.build({ description: 'Took a cold bath' });
  11. note.save().then(() => {
  12. console.log('new task saved');
  13. }).finally(() => {
  14. sequelize.close();
  15. });

本示例使用build()save()创建一个新的笔记。

Sequelize findById

使用findById(),我们通过其 ID 查找特定行。

find_by_id.js

  1. const Sequelize = require('sequelize');
  2. const path = 'mysql://user12:12user@localhost:3306/mydb';
  3. const sequelize = new Sequelize(path, {
  4. operatorsAliases: false,
  5. logging: false
  6. });
  7. let Note = sequelize.define('notes', {
  8. description: Sequelize.STRING
  9. });
  10. Note.findById(2).then((note) => {
  11. console.log(note.get({ plain: true }));
  12. console.log('********************')
  13. console.log(`id: ${note.id}, description: ${note.description}`);
  14. }).finally(() => {
  15. sequelize.close();
  16. });

该示例查找带有 ID 2 的笔记。

  1. console.log(note.get({ plain: true }));

默认情况下,Sequelize 返回大量元数据。 要关闭数据,我们使用plain: true选项。

  1. $ node find_by_id.js
  2. { id: 2,
  3. description: 'Visited friend',
  4. createdAt: 2018-10-21T14:34:28.000Z,
  5. updatedAt: 2018-10-21T14:34:28.000Z }
  6. ********************
  7. id: 2, description: Visited friend

我们将行打印两次。 在第一种情况下,我们返回所有数据。 在第二种情况下,我们仅选择两个字段。

Sequelize findOne

findOne()方法搜索单个行。

find_one.js

  1. const Sequelize = require('sequelize');
  2. const path = 'mysql://user12:12user@localhost:3306/mydb';
  3. const sequelize = new Sequelize(path, {
  4. operatorsAliases: false,
  5. logging: false
  6. });
  7. let Note = sequelize.define('notes', {
  8. description: Sequelize.STRING
  9. });
  10. Note.findOne({ where: { id: 1 } }).then(note => {
  11. console.log(note.get({ plain: true }));
  12. }).finally(() => {
  13. sequelize.close();
  14. });

该示例使用find_one()返回表的第一行。 where选项指定要查找的 ID。

  1. $ node find_one.js
  2. { id: 1,
  3. description: 'Tai chi in the morning',
  4. createdAt: 2018-10-21T14:34:28.000Z,
  5. updatedAt: 2018-10-21T14:34:28.000Z }

这是输出。

Sequelize asyncawait

在下一个示例中,我们使用asyncawait关键字。

find_one2.js

  1. const Sequelize = require('sequelize');
  2. const path = 'mysql://user12:12user@localhost:3306/mydb';
  3. const sequelize = new Sequelize(path, {
  4. operatorsAliases: false,
  5. logging: false
  6. });
  7. let Note = sequelize.define('notes', {
  8. description: Sequelize.STRING
  9. });
  10. async function getOneNote() {
  11. let user = await Note.findOne();
  12. console.log(user.get('description'));
  13. sequelize.close();
  14. }
  15. getOneNote();

我们使用asyncawait关键字返回带有findOne()的第一行。

Sequelize 计数

count()方法计算表中的行数。

count_rows.js

  1. const Sequelize = require('sequelize');
  2. const path = 'mysql://user12:12user@localhost:3306/mydb';
  3. const sequelize = new Sequelize(path, {
  4. operatorsAliases: false,
  5. logging: false
  6. });
  7. let Note = sequelize.define('notes', {
  8. description: Sequelize.STRING
  9. });
  10. async function countRows() {
  11. let n = await Note.count();
  12. console.log(`There are ${n} rows`);
  13. sequelize.close();
  14. }
  15. countRows();

该示例计算notes表中的行数。

  1. $ node count_rows.js
  2. There are 7 rows

目前,表格中有 7 行。

Sequelize 删除行

使用destroy()方法删除一行。 它返回已删除的行数。

delete_row.js

  1. const Sequelize = require('sequelize');
  2. const path = 'mysql://user12:12user@localhost:3306/mydb';
  3. const sequelize = new Sequelize(path, {
  4. operatorsAliases: false,
  5. logging: false
  6. });
  7. let Note = sequelize.define('notes', {
  8. description: Sequelize.STRING
  9. });
  10. async function deleteRow() {
  11. let n = await Note.destroy({ where: { id: 2 } });
  12. console.log(`number of deleted rows: ${n}`);
  13. sequelize.close();
  14. }
  15. deleteRow();

该示例删除 ID 为 2 的行。

Sequelize 更新行

update()方法更新一行。

update_row.js

  1. const Sequelize = require('sequelize');
  2. const path = 'mysql://user12:12user@localhost:3306/mydb';
  3. const sequelize = new Sequelize(path, {
  4. operatorsAliases: false,
  5. logging: false
  6. });
  7. let Note = sequelize.define('notes', {
  8. description: Sequelize.STRING
  9. });
  10. async function updateRow() {
  11. let id = await Note.update(
  12. { description: 'Finished reading history book' },
  13. { where: { id: 1 } });
  14. sequelize.close();
  15. }
  16. updateRow();

该示例更新了第一行的描述。

Sequelize findAll

findAll()方法搜索多个实例。

find_all.js

  1. const Sequelize = require('sequelize');
  2. const path = 'mysql://user12:12user@localhost:3306/mydb';
  3. const sequelize = new Sequelize(path, {
  4. operatorsAliases: false,
  5. logging: false
  6. });
  7. let Note = sequelize.define('notes', {
  8. description: Sequelize.STRING
  9. });
  10. async function findAllRows() {
  11. let notes = await Note.findAll({ raw: true });
  12. console.log(notes);
  13. sequelize.close();
  14. }
  15. findAllRows();

该示例使用findAll()从数据库表中检索所有行。

  1. let notes = await Note.findAll({ raw: true });

raw: true选项关闭元数据。

  1. $ node find_all.js
  2. [ { id: 1,
  3. description: 'Finished reading history book',
  4. createdAt: 2018-10-21T14:34:28.000Z,
  5. updatedAt: 2018-10-21T16:00:22.000Z },
  6. { id: 2,
  7. description: 'Visited friend',
  8. createdAt: 2018-10-21T14:34:28.000Z,
  9. updatedAt: 2018-10-21T14:34:28.000Z },
  10. { id: 3,
  11. description: 'Went to cinema',
  12. createdAt: 2018-10-21T14:34:28.000Z,
  13. updatedAt: 2018-10-21T14:34:28.000Z },
  14. { id: 4,
  15. description: 'Listened to music',
  16. createdAt: 2018-10-21T14:34:28.000Z,
  17. updatedAt: 2018-10-21T14:34:28.000Z },
  18. { id: 5,
  19. description: 'Watched TV all day',
  20. createdAt: 2018-10-21T14:34:28.000Z,
  21. updatedAt: 2018-10-21T14:34:28.000Z },
  22. { id: 6,
  23. description: 'Walked for a hour',
  24. createdAt: 2018-10-21T14:34:28.000Z,
  25. updatedAt: 2018-10-21T14:34:28.000Z },
  26. { id: 7,
  27. description: 'Took a cold bath',
  28. createdAt: 2018-10-21T14:49:51.000Z,
  29. updatedAt: 2018-10-21T14:49:51.000Z } ]

该示例返回了七行。

Seqelize 选择列

使用attributes选项,我们可以选择要包括在查询中的列。

columns.js

  1. const Sequelize = require('sequelize');
  2. const path = 'mysql://user12:12user@localhost:3306/mydb';
  3. const sequelize = new Sequelize(path, {
  4. operatorsAliases: false,
  5. });
  6. let Note = sequelize.define('notes', {
  7. description: Sequelize.STRING
  8. });
  9. async function getTwoColumns() {
  10. let notes = await Note.findAll({ attributes: ['id', 'description'], raw: true });
  11. console.log(notes);
  12. sequelize.close();
  13. }
  14. getTwoColumns();

在示例中,我们选择iddescription列。

  1. $ node columns.js
  2. Executing (default): SELECT `id`, `description` FROM `notes` AS `notes`;
  3. [ { id: 1, description: 'Finished reading history book' },
  4. { id: 3, description: 'Went to cinema' },
  5. { id: 4, description: 'Listened to music' },
  6. { id: 5, description: 'Watched TV all day' },
  7. { id: 6, description: 'Walked for a hour' } ]

这是输出。

Seqelize offsetlimit

使用offsetlimit属性,我们可以定义findAll()方法中要包括的行的初始跳过和行数。

offset_limit.js

  1. const Sequelize = require('sequelize');
  2. const path = 'mysql://user12:12user@localhost:3306/mydb';
  3. const sequelize = new Sequelize(path, {
  4. operatorsAliases: false,
  5. logging: false
  6. });
  7. let Note = sequelize.define('notes', {
  8. description: Sequelize.STRING
  9. });
  10. async function getRows() {
  11. let notes = await Note.findAll({ offset: 2, limit: 3,
  12. attributes: ['id', 'description'], raw: true
  13. });
  14. console.log(notes);
  15. sequelize.close();
  16. }
  17. getRows();

该示例从第二行开始还原三行。

  1. $ node offset_limit.js
  2. [ { id: 3, description: 'Went to cinema' },
  3. { id: 4, description: 'Listened to music' },
  4. { id: 5, description: 'Watched TV all day' } ]

这是输出。

Seqelize 顺序排序

为了在查询中包含ORDER BY子句,我们使用order选项。

order_by.js

  1. const Sequelize = require('sequelize');
  2. const path = 'mysql://user12:12user@localhost:3306/mydb';
  3. const sequelize = new Sequelize(path, {
  4. operatorsAliases: false
  5. });
  6. let Note = sequelize.define('notes', {
  7. description: Sequelize.STRING
  8. });
  9. async function getRows() {
  10. let notes = await Note.findAll({
  11. order: [['description', 'DESC']],
  12. attributes: ['id', 'description'], raw: true
  13. })
  14. console.log(notes);
  15. sequelize.close();
  16. }
  17. getRows();

在示例中,我们从表中选择所有行,并按描述以降序对其进行排序。

  1. $ node order_by.js
  2. Executing (default): SELECT `id`, `description` FROM `notes` AS `notes`
  3. ORDER BY `notes`.`description` DESC;
  4. [ { id: 3, description: 'Went to cinema'}, { id: 5, description: 'Watched TV all day' },
  5. { id: 6, description: 'Walked for a hour'}, { id: 2, description: 'Visited friend' },
  6. { id: 1, description: 'Tai chi in the morning' },
  7. { id: 4, description: 'Listened to music' } ]

从输出中我们可以看到ORDER BY子句已添加到查询中。

Seqelize Op.IN运算符

使用Op.IN运算符,我们可以确定指定的值是否与子查询或列表中的任何值匹配。

operator_in.js

  1. const Sequelize = require('sequelize');
  2. const Op = Sequelize.Op;
  3. const path = 'mysql://user12:12user@localhost:3306/mydb';
  4. const sequelize = new Sequelize(path, {
  5. operatorsAliases: false,
  6. logging: false
  7. });
  8. let Note = sequelize.define('notes', {
  9. description: Sequelize.STRING
  10. });
  11. async function getRows() {
  12. let notes = await Note.findAll({ where: { id: { [Op.in]: [3, 6] } } });
  13. notes.forEach(note => {
  14. console.log(`${note.id}: ${note.description}`);
  15. });
  16. sequelize.close();
  17. }
  18. getRows();

在示例中,我们选择与 ID 列表匹配的所有行。

  1. $ node operator_in.js
  2. 3: Went to cinema
  3. 6: Walked for a hour

输出显示两行:ID 为 3 和 6。

Seqelize Op.between运算符

使用Op.between运算符,我们可以确定指定值是否与给定范围内的任何值匹配。

operator_between.js

  1. const Sequelize = require('sequelize');
  2. const Op = Sequelize.Op;
  3. const path = 'mysql://user12:12user@localhost:3306/mydb';
  4. const sequelize = new Sequelize(path, {
  5. operatorsAliases: false,
  6. logging: false
  7. });
  8. let Note = sequelize.define('notes', {
  9. description: Sequelize.STRING
  10. });
  11. async function getRows() {
  12. let notes = await Note.findAll({ where: { id: { [Op.between]: [3, 6] } }});
  13. notes.forEach(note => {
  14. console.log(`${note.id}: ${note.description}`);
  15. });
  16. sequelize.close();
  17. }
  18. getRows();

该示例使用Op.between运算符显示行3..6

Sequelize belongsTo

Sequelize belongsTo在源模型和提供的目标模型之间创建一对一的关联。 外键添加在源上。

belongs_to.js

  1. const Sequelize = require('sequelize');
  2. const path = 'mysql://user12:12user@localhost:3306/mydb';
  3. const sequelize = new Sequelize(path, {
  4. operatorsAliases: false,
  5. logging: false
  6. });
  7. let Employee = sequelize.define('employees', {
  8. name: Sequelize.STRING
  9. });
  10. let Project = sequelize.define('projects', {
  11. name: Sequelize.STRING
  12. });
  13. Employee.belongsTo(Project);
  14. let employees = [
  15. { name: 'Jane Brown' }, { name: 'Lucia Benner' }, { name: 'Peter Novak' }
  16. ];
  17. sequelize.sync({ force: true }).then(() => {
  18. return Employee.bulkCreate(employees);
  19. }).then((employees) => {
  20. let works = [];
  21. let i = 0;
  22. employees.forEach(employee => {
  23. let pname = 'Project ' + String.fromCharCode('A'.charCodeAt() + i);
  24. i++;
  25. let work = Project.create({ name: pname }).then(project => {
  26. employee.setProject(project);
  27. });
  28. works.push(work);
  29. });
  30. Promise.all(works).then(() => sequelize.close());
  31. console.log('finish');
  32. });

在示例中,我们有两个模型:EmployeeProject。 我们使用belongsTo在两个模型之间创建一对一关联。 我们将数据添加到模型中。

  1. let Employee = sequelize.define('employees', {
  2. name: Sequelize.STRING
  3. });
  4. let Project = sequelize.define('projects', {
  5. name: Sequelize.STRING
  6. });

我们定义了两个模型。

  1. Employee.belongsTo(Project);

我们在EmployeeProject模型之间创建一对一关联。 外键在Employee中生成。

  1. let employees = [
  2. { name: 'Jane Brown' }, { name: 'Lucia Benner' }, { name: 'Peter Novak' }
  3. ];

我们将创建三名员工。

  1. let works = [];

works数组用于存储生成的Promise

  1. employees.forEach(employee => {
  2. let pname = 'Project ' + String.fromCharCode('A'.charCodeAt() + i);
  3. i++;
  4. let work = Project.create({ name: pname }).then(project => {
  5. employee.setProject(project);
  6. });
  7. works.push(work);
  8. });

我们遍历所有员工,并为每个员工生成一个新项目。 setProject()添加了一个新项目。 Project.create()生成一个新的Promise,将其添加到works数组中。

  1. Promise.all(works).then(() => sequelize.close());

Promise.all()解析数组中的所有promise

接下来,我们检索联接的数据。 当我们生成还从其他表中获取关联数据的查询时,我们会渴望加载。 通过include选项启用了预先加载。

belongs_to2.js

  1. const Sequelize = require('sequelize');
  2. const path = 'mysql://user12:12user@localhost:3306/mydb';
  3. const sequelize = new Sequelize(path, {
  4. operatorsAliases: false,
  5. logging: false
  6. });
  7. let Employee = sequelize.define('employees', {
  8. name: Sequelize.STRING
  9. });
  10. let Project = sequelize.define('projects', {
  11. name: Sequelize.STRING
  12. });
  13. Employee.belongsTo(Project);
  14. Employee.findAll({include: [Project]}).then(employees => {
  15. employees.forEach(employee => {
  16. console.log(`${employee.name} is in project ${employee.project.name}`);
  17. });
  18. }).finally(() => {
  19. sequelize.close();
  20. });

该示例列出了员工及其项目。

  1. Employee.findAll({include: [Project]}).then(employees => {

在查询中,我们添加include选项,其中包括关联的模型。

  1. $ node belongs_to2.js
  2. Jane Brown is in project Project A
  3. Lucia Benner is in project Project B
  4. Peter Novak is in project Project C

这是输出。

双向化一对一关系

双向关系在两个方向上均有效。 我们可以从源模型引用目标模型,反之亦然。 为了在模型之间创建双向一对一关系,我们将其与belongsTo()hasOne()映射。

bidi_one2one.js

  1. const Sequelize = require('sequelize');
  2. const path = 'mysql://user12:12user@localhost:3306/mydb';
  3. const sequelize = new Sequelize(path, {
  4. operatorsAliases: false,
  5. logging: false
  6. });
  7. let Employee = sequelize.define('employees', {
  8. name: Sequelize.STRING
  9. });
  10. let Project = sequelize.define('projects', {
  11. name: Sequelize.STRING
  12. });
  13. Employee.belongsTo(Project);
  14. Project.hasOne(Employee);
  15. Project.findAll({include: [Employee]}).then(projects => {
  16. projects.forEach(project => {
  17. console.log(`${project.name} belongs to user ${project.employee.name}`);
  18. });
  19. }).finally(() => {
  20. sequelize.close();
  21. });

在此示例中,我们从每个项目中检索一名员工。

  1. Employee.belongsTo(Project);
  2. Project.hasOne(Employee);

为了实现双向关联,我们还使用hasOne()映射了模型。

  1. $ node bidi_one2one.js
  2. Project A belongs to user Jane Brown
  3. Project B belongs to user Lucia Benner
  4. Project C belongs to user Peter Novak

这是输出。

Sequelize hasMany

Sequelize hasMany在源和提供的目标之间创建多对一关联。 外键添加到目标上。

one_to_many.js

  1. const Sequelize = require('sequelize');
  2. const path = 'mysql://user12:12user@localhost:3306/mydb';
  3. const sequelize = new Sequelize(path, {
  4. operatorsAliases: false,
  5. logging: false
  6. });
  7. let User = sequelize.define('user', {
  8. name: Sequelize.STRING,
  9. });
  10. let Task = sequelize.define('task', {
  11. description: Sequelize.STRING,
  12. });
  13. User.hasMany(Task);
  14. async function createTables() {
  15. await User.sync();
  16. await Task.sync();
  17. console.log('done');
  18. sequelize.close();
  19. }
  20. createTables();

首先,我们创建两个表:userstasks

在第二步中,我们用数据填充表。

one_to_many2.js

  1. const Sequelize = require('sequelize');
  2. const path = 'mysql://user12:12user@localhost:3306/mydb';
  3. const sequelize = new Sequelize(path, {
  4. operatorsAliases: false,
  5. logging: false
  6. });
  7. let User = sequelize.define('user', {
  8. name: Sequelize.STRING
  9. });
  10. let Task = sequelize.define('task', {
  11. description: Sequelize.STRING,
  12. });
  13. User.hasMany(Task);
  14. let mytasks1 = [
  15. { description: 'write memo' }, { description: 'check accounts' }
  16. ];
  17. let mytasks2 = [
  18. { description: 'make two phone calls' },
  19. { description: 'read new emails' },
  20. { description: 'arrange meeting' }
  21. ];
  22. async function addUsersTasks() {
  23. let user1 = await User.create({ name: 'John Doe' });
  24. let tasks1 = await Task.bulkCreate(mytasks1);
  25. await user1.setTasks(tasks1);
  26. let user2 = await User.create({ name: 'Debbie Griffin' });
  27. let tasks2 = await Task.bulkCreate(mytasks2);
  28. await user2.setTasks(tasks2);
  29. console.log('done');
  30. sequelize.close();
  31. }
  32. addUsersTasks();

我们有两个执行某些任务的用户。

  1. let user1 = await User.create({ name: 'John Doe' });

使用User.create()创建一个新用户。

  1. let tasks1 = await Task.bulkCreate(mytasks1);

使用Task.bulkCreate()生成新任务。

  1. await user1.setTasks(tasks1);

使用setTasks()将任务添加到用户。

最后,我们检索数据。

one_to_many3.js

  1. const Sequelize = require('sequelize');
  2. const path = 'mysql://user12:12user@localhost:3306/mydb';
  3. const sequelize = new Sequelize(path, {
  4. operatorsAliases: false,
  5. logging: false
  6. });
  7. let User = sequelize.define('user', {
  8. name: Sequelize.STRING
  9. });
  10. let Task = sequelize.define('task', {
  11. description: Sequelize.STRING,
  12. });
  13. User.hasMany(Task);
  14. async function showUsersTasks() {
  15. let users = await User.findAll({ include: [Task] });
  16. users.forEach(user => {
  17. console.log(`${user.name} has tasks: `);
  18. let tasks = user.tasks;
  19. tasks.forEach(task => {
  20. console.log(` * ${task.description}`);
  21. })
  22. });
  23. console.log('done');
  24. sequelize.close();
  25. }
  26. showUsersTasks();

在示例中,我们显示了所有用户及其关联的任务。

  1. let users = await User.findAll({ include: [Task] });

要启用紧急加载,我们使用include选项。 急切的加载是在查询中也检索关联的数据时。

  1. $ node one_to_many3.js
  2. John Doe has tasks:
  3. * write memo * check accountsDebbie Griffin has tasks:
  4. * make two phone calls * read new emails
  5. * arrange meeting
  6. done

这是输出。

双向一对多关系

双向一对多关系在两个方向上均有效。 为了在模型之间建立双向的一对多关系,我们使用hasMany()belongsTo()映射它们。

bidi_one2many.js

  1. const Sequelize = require('sequelize');
  2. const path = 'mysql://user12:12user@localhost:3306/mydb';
  3. const sequelize = new Sequelize(path, {
  4. operatorsAliases: false,
  5. logging: false
  6. });
  7. let User = sequelize.define('user', {
  8. name: Sequelize.STRING
  9. });
  10. let Task = sequelize.define('task', {
  11. description: Sequelize.STRING
  12. });
  13. User.hasMany(Task);
  14. Task.belongsTo(User);
  15. async function showTaskUser() {
  16. let task = await Task.findOne({ include: [User] });
  17. console.log(`${task.description} belongs to ${task.user.name}`);
  18. sequelize.close();
  19. }
  20. showTaskUser();

该示例从检索的任务中获取用户。

  1. User.hasMany(Task);
  2. Task.belongsTo(User);

为了实现双向一对一关系,我们使用hasMany()belongsTo()映射模型。

  1. $ node bidi_one2many.js
  2. write memo belongs to John Doe

这是输出。

在本教程中,我们使用了Seqeulize库。 我们创建了一些与 MySQL 交互的命令行程序。

您可能也对以下相关教程感兴趣: Knex.js 教程Node Postgres 教程Lodash 教程书架教程, 或列出所有 JavaScript 教程