这是我参与2022首次更文挑战的第6天,活动详情查看:2022首次更文挑战
Hooks(生命周期事件)是在执行 sequelize 中的调用之前和之后调用的函数., 例如,如果要在保存之前始终在模型上设置一个值,则可以添加一个 beforeUpdate hook进行操作
连接 Hooks
Sequelize 提供了四个 hook,它们在获得或释放数据库连接之前和之后立即执行:
-
sequelize.beforeConnect(callback)- 回调具有以下形式
async (config) => /* ... */
- 回调具有以下形式
-
sequelize.afterConnect(callback)- 回调具有以下形式
async (connection, config) => /* ... */
- 回调具有以下形式
-
sequelize.beforeDisconnect(callback)- 回调具有以下形式
async (connection) => /* ... */
- 回调具有以下形式
-
sequelize.afterDisconnect(callback)- 回调具有以下形式
async (connection) => /* ... */
- 回调具有以下形式
如果需要异步获取数据库凭据,或者需要在创建低级数据库连接后直接访问它,例如,可以从令牌存储异步获取数据库密码,并使用新的凭证对 Sequelize 的配置对象进行更新:
这些 hook 只能声明为永久全局 hook,因为所有模型都共享连接池
sequelize.beforeConnect(async (config) => {
config.password = await getAuthToken();
});
常见 Hooks 触发顺序
- beforeBulkCreate(instances, options), beforeBulkDestroy(options), beforeBulkUpdate(options)
- beforeValidate(instance, options)
- afterValidate(instance, options), validationFailed(instance, options, error)
- beforeCreate(instance, options), beforeDestroy(instance, options), beforeUpdate(instance, options), beforeSave(instance, options), beforeUpsert(values, options)
- afterCreate(instance, options), afterDestroy(instance, options), afterUpdate(instance, options), afterSave(instance, options), afterUpsert(created, options)
- afterBulkCreate(instances, options), afterBulkDestroy(options), afterBulkUpdate(options)
声明 Hooks
Hook 的参数通过引用传递, 相当于可以更改值, 这些出现在 insert / update 语句中, 一个 hook 可能包含异步动作 - 在这种情况下, hook 函数应该返回一个 Promise对象
// 方法 1 通过 .init() 方法
class User extends Model {}
User.init({
username: DataTypes.STRING,
mood: {
type: DataTypes.ENUM,
values: ['happy', 'sad', 'neutral']
}
}, {
hooks: {
beforeValidate: (user, options) => {
user.mood = 'happy';
},
afterValidate: (user, options) => {
user.username = 'Toni';
}
},
sequelize
});
// 方法 2 通过 .addHook() 方法
User.addHook('beforeValidate', (user, options) => {
user.mood = 'happy';
});
User.addHook('afterValidate', 'someCustomName', (user, options) => {
return Promise.reject(new Error("I'm afraid I can't let you do that!"));
});
// 方法 3 通过 direct 方法
User.beforeCreate(async (user, options) => {
const hashedPassword = await hashPassword(user.password);
user.password = hashedPassword;
});
User.afterValidate('myHookAfter', (user, options) => {
user.username = 'Toni';
});
删除 hooks
只能删除带有名称参数的 hook.
同名的 hook 调用 .removeHook() 将删除所有对象
class Book extends Model {}
Book.init({
title: DataTypes.STRING
}, { sequelize });
Book.addHook('afterCreate', 'notifyUsers', (book, options) => {
// ...
});
Book.removeHook('afterCreate', 'notifyUsers');