Skip to main content
Version: v6 - stable

模型实例

如你所知,型号是 ES6 类。该类的一个实例代表该模型中的一个对象(映射到数据库中表的一行)。这样,模型实例就是 DAO

¥As you already know, a model is an ES6 class. An instance of the class represents one object from that model (which maps to one row of the table in the database). This way, model instances are DAOs.

对于本指南,将假定以下设置:

¥For this guide, the following setup will be assumed:

const { Sequelize, Model, DataTypes } = require('sequelize');
const sequelize = new Sequelize('sqlite::memory:');

const User = sequelize.define('user', {
name: DataTypes.TEXT,
favoriteColor: {
type: DataTypes.TEXT,
defaultValue: 'green',
},
age: DataTypes.INTEGER,
cash: DataTypes.INTEGER,
});

(async () => {
await sequelize.sync({ force: true });
// Code here
})();

创建实例

¥Creating an instance

尽管模型是一个类,但你不应该直接使用 new 运算符创建实例。相反,应该使用 build 方法:

¥Although a model is a class, you should not create instances by using the new operator directly. Instead, the build method should be used:

const jane = User.build({ name: 'Jane' });
console.log(jane instanceof User); // true
console.log(jane.name); // "Jane"

然而,上面的代码根本不与数据库通信(注意,它甚至不是异步的)!这是因为 build 方法仅创建一个表示可以映射到数据库的数据的对象。为了真正将该实例保存(即持久)到数据库中,应使用 save 方法:

¥However, the code above does not communicate with the database at all (note that it is not even asynchronous)! This is because the build method only creates an object that represents data that can be mapped to a database. In order to really save (i.e. persist) this instance in the database, the save method should be used:

await jane.save();
console.log('Jane was saved to the database!');

请注意,从上面代码片段中 await 的用法来看,save 是一个异步方法。事实上,几乎每个 Sequelize 方法都是异步的;build 是极少数的例外之一。

¥Note, from the usage of await in the snippet above, that save is an asynchronous method. In fact, almost every Sequelize method is asynchronous; build is one of the very few exceptions.

一个非常有用的快捷方式:create 方法

¥A very useful shortcut: the create method

Sequelize 提供了 create 方法,它将上面显示的 buildsave 方法组合成一个方法:

¥Sequelize provides the create method, which combines the build and save methods shown above into a single method:

const jane = await User.create({ name: 'Jane' });
// Jane exists in the database now!
console.log(jane instanceof User); // true
console.log(jane.name); // "Jane"

注意:记录实例

¥Note: logging instances

尝试将模型实例直接记录到 console.log 会产生很多混乱,因为 Sequelize 实例附加了很多东西。相反,你可以使用 .toJSON() 方法(顺便说一下,它会自动保证实例能够很好地进行 JSON.stringify 处理)。

¥Trying to log a model instance directly to console.log will produce a lot of clutter, since Sequelize instances have a lot of things attached to them. Instead, you can use the .toJSON() method (which, by the way, automatically guarantees the instances to be JSON.stringify-ed well).

const jane = await User.create({ name: 'Jane' });
// console.log(jane); // Don't do this
console.log(jane.toJSON()); // This is good!
console.log(JSON.stringify(jane, null, 4)); // This is also good!

默认值

¥Default values

构建的实例将自动获取默认值:

¥Built instances will automatically get default values:

const jane = User.build({ name: 'Jane' });
console.log(jane.favoriteColor); // "green"

更新实例

¥Updating an instance

如果更改实例的某个字段的值,再次调用 save 将会相应更新:

¥If you change the value of some field of an instance, calling save again will update it accordingly:

const jane = await User.create({ name: 'Jane' });
console.log(jane.name); // "Jane"
jane.name = 'Ada';
// the name is still "Jane" in the database
await jane.save();
// Now the name was updated to "Ada" in the database!

你可以使用 set 方法一次更新多个字段:

¥You can update several fields at once with the set method:

const jane = await User.create({ name: 'Jane' });

jane.set({
name: 'Ada',
favoriteColor: 'blue',
});
// As above, the database still has "Jane" and "green"
await jane.save();
// The database now has "Ada" and "blue" for name and favorite color

请注意,此处的 save() 还将保留对此实例所做的任何其他更改,而不仅仅是先前 set 调用中的更改。如果你想更新一组特定的字段,你可以使用 update

¥Note that the save() here will also persist any other changes that have been made on this instance, not just those in the previous set call. If you want to update a specific set of fields, you can use update:

const jane = await User.create({ name: 'Jane' });
jane.favoriteColor = 'blue';
await jane.update({ name: 'Ada' });
// The database now has "Ada" for name, but still has the default "green" for favorite color
await jane.save();
// Now the database has "Ada" for name and "blue" for favorite color

删除实例

¥Deleting an instance

你可以通过调用 destroy 来删除实例:

¥You can delete an instance by calling destroy:

const jane = await User.create({ name: 'Jane' });
console.log(jane.name); // "Jane"
await jane.destroy();
// Now this entry was removed from the database

重新加载实例

¥Reloading an instance

你可以通过调用 reload 从数据库重新加载实例:

¥You can reload an instance from the database by calling reload:

const jane = await User.create({ name: 'Jane' });
console.log(jane.name); // "Jane"
jane.name = 'Ada';
// the name is still "Jane" in the database
await jane.reload();
console.log(jane.name); // "Jane"

重新加载调用生成 SELECT 查询以从数据库获取最新数据。

¥The reload call generates a SELECT query to get the up-to-date data from the database.

只保存部分字段

¥Saving only some fields

可以通过传递列名数组来定义调用 save 时应保存哪些属性。

¥It is possible to define which attributes should be saved when calling save, by passing an array of column names.

当你根据先前定义的对象设置属性时(例如,当你通过 Web 应用的表单获取对象的值时),这非常有用。此外,这在 update 实现中内部使用。它是这样的:

¥This is useful when you set attributes based on a previously defined object, for example, when you get the values of an object via a form of a web app. Furthermore, this is used internally in the update implementation. This is how it looks like:

const jane = await User.create({ name: 'Jane' });
console.log(jane.name); // "Jane"
console.log(jane.favoriteColor); // "green"
jane.name = 'Jane II';
jane.favoriteColor = 'blue';
await jane.save({ fields: ['name'] });
console.log(jane.name); // "Jane II"
console.log(jane.favoriteColor); // "blue"
// The above printed blue because the local object has it set to blue, but
// in the database it is still "green":
await jane.reload();
console.log(jane.name); // "Jane II"
console.log(jane.favoriteColor); // "green"

保存的变化意识

¥Change-awareness of save

save 方法在内部进行了优化,只更新真正更改的字段。这意味着,如果你不更改任何内容并调用 save,Sequelize 将知道保存是多余的并且不执行任何操作,即不会生成任何查询(它仍然会返回 Promise,但会立即解析)。

¥The save method is optimized internally to only update fields that really changed. This means that if you don't change anything and call save, Sequelize will know that the save is superfluous and do nothing, i.e., no query will be generated (it will still return a Promise, but it will resolve immediately).

此外,如果在调用 save 时仅更改了少数属性,则只有这些字段将在 UPDATE 查询中发送,以提高性能。

¥Also, if only a few attributes have changed when you call save, only those fields will be sent in the UPDATE query, to improve performance.

递增和递减整数值

¥Incrementing and decrementing integer values

为了增加/减少实例的值而不遇到并发问题,Sequelize 提供了 incrementdecrement 实例方法。

¥In order to increment/decrement values of an instance without running into concurrency issues, Sequelize provides the increment and decrement instance methods.

const jane = await User.create({ name: 'Jane', age: 100 });
const incrementResult = await jane.increment('age', { by: 2 });
// Note: to increment by 1 you can omit the `by` option and just do `user.increment('age')`

// In PostgreSQL, `incrementResult` will be the updated user, unless the option
// `{ returning: false }` was set (and then it will be undefined).

// In other dialects, `incrementResult` will be undefined. If you need the updated instance, you will have to call `user.reload()`.

你还可以一次增加多个字段:

¥You can also increment multiple fields at once:

const jane = await User.create({ name: 'Jane', age: 100, cash: 5000 });
await jane.increment({
age: 2,
cash: 100,
});

// If the values are incremented by the same amount, you can use this other syntax as well:
await jane.increment(['age', 'cash'], { by: 2 });

递减的工作方式完全相同。

¥Decrementing works in the exact same way.