Sequelize 学习笔记
# Sequelize 中文文档入门 (opens new window)
# 核心概念
# 基本设置
# 表名推断
默认情况下,当未提供表名时,Sequelize 会自动将模型名复数并将其用作表名. 这种复数是通过称为 inflection (opens new window) 的库在后台完成的,因此可以正确计算不规则的复数(例如 person -> people
).
# 强制表名称等于模型名称
sequelize.define('User', {
// ... (属性)
}, {
freezeTableName: true
});
2
3
4
5
# 直接提供表名
sequelize.define('User', {
// ... (属性)
}, {
tableName: 'Employees'
});
2
3
4
5
# 模型同步
User.sync()
- 如果表不存在,则创建该表(如果已经存在,则不执行任何操作)User.sync({ force: true })
- 将创建表,如果表已经存在,则将其首先删除User.sync({ alter: true })
- 这将检查数据库中表的当前状态(它具有哪些列,它们的数据类型等),然后在表中进行必要的更改以使其与模型匹配
await User.sync({ force: true });
console.log("用户模型表刚刚(重新)创建!");
2
# 时间戳
默认情况下,Sequelize 使用数据类型 DataTypes.DATE
自动向每个模型添加 createdAt
和 updatedAt
字段. 这些字段会自动进行管理 - 每当你使用Sequelize 创建或更新内容时,这些字段都会被自动设置. createdAt
字段将包含代表创建时刻的时间戳,而 updatedAt
字段将包含最新更新的时间戳.
对于带有 timestamps: false
参数的模型,可以禁用此行为:
sequelize.define('User', {
// ... (属性)
}, {
timestamps: false
});
2
3
4
5
也可以只启用 createdAt
/updatedAt
之一,并为这些列提供自定义名称:
class Foo extends Model {}
Foo.init({ /* 属性 */ }, {
sequelize,
// 不要忘记启用时间戳!
timestamps: true,
// 不想要 createdAt
createdAt: false,
// 想要 updatedAt 但是希望名称叫做 updateTimestamp
updatedAt: 'updateTimestamp'
});
2
3
4
5
6
7
8
9
10
# 获取的值变更, 设置值变更(getter, setter)
# 获取的值变更
const User = sequelize.define('user', {
// 假设我们想要以大写形式查看每个用户名,
// 即使它们在数据库本身中不一定是大写的
username: {
type: DataTypes.STRING,
get() {
const rawValue = this.getDataValue(username);
return rawValue ? rawValue.toUpperCase() : null;
}
}
});
2
3
4
5
6
7
8
9
10
11
# 设置值变更
const User = sequelize.define('user', {
username: DataTypes.STRING,
password: {
type: DataTypes.STRING,
set(value) {
// 在数据库中以明文形式存储密码是很糟糕的.
// 使用适当的哈希函数来加密哈希值更好.
this.setDataValue('password', hash(value));
}
}
});
2
3
4
5
6
7
8
9
10
11
# 模型 Model
# 定义模型
class Foo extends Model {}
Foo.init({
// 如果未设置,实例化将自动将标志设置为true
flag: { type: DataTypes.BOOLEAN, allowNull: false, defaultValue: true },
// 日期的默认值=>当前时间
myDate: { type: DataTypes.DATE, defaultValue: DataTypes.NOW },
// setting allowNull to false will add NOT NULL to the column, which means an error will be
// thrown from the DB when the query is executed if the column is null. If you want to check that a value
// is not null before querying the DB, look at the validations section below.
title: { type: DataTypes.STRING, allowNull: false },
// Creating two objects with the same value will throw an error. The unique property can be either a
// boolean, or a string. If you provide the same string for multiple columns, they will form a
// composite unique key.
uniqueOne: { type: DataTypes.STRING, unique: 'compositeIndex' },
uniqueTwo: { type: DataTypes.INTEGER, unique: 'compositeIndex' },
// The unique property is simply a shorthand to create a unique constraint.
someUnique: { type: DataTypes.STRING, unique: true },
// Go on reading for further information about primary keys
identifier: { type: DataTypes.STRING, primaryKey: true },
// autoIncrement can be used to create auto_incrementing integer columns
incrementMe: { type: DataTypes.INTEGER, autoIncrement: true },
// You can specify a custom column name via the 'field' attribute:
fieldWithUnderscores: { type: DataTypes.STRING, field: 'field_with_underscores' },
// It is possible to create foreign keys:
bar_id: {
type: DataTypes.INTEGER,
references: {
// This is a reference to another model
model: Bar,
// This is the column name of the referenced model
key: 'id',
// With PostgreSQL, it is optionally possible to declare when to check the foreign key constraint, passing the Deferrable type.
deferrable: Deferrable.INITIALLY_IMMEDIATE
// Options:
// - `Deferrable.INITIALLY_IMMEDIATE` - Immediately check the foreign key constraints
// - `Deferrable.INITIALLY_DEFERRED` - Defer all foreign key constraint check to the end of a transaction
// - `Deferrable.NOT` - Don't defer the checks at all (default) - This won't allow you to dynamically change the rule in a transaction
}
},
// Comments can only be added to columns in MySQL, MariaDB, PostgreSQL and MSSQL
commentMe: {
type: DataTypes.INTEGER,
comment: 'This is a column name that has a comment'
}
}, {
sequelize,
modelName: 'foo',
// Using `unique: true` in an attribute above is exactly the same as creating the index in the model's options:
indexes: [{ unique: true, fields: ['someUnique'] }]
});
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# 验证和约束
使用自定义错误消息代替validator提供的错误消息。使用一个对象,而不是纯值或参数数组,例如验证器不需要参数,可以给自定义消息
isInt: {
msg: "必须是整数"
}
2
3
你也可以有条件地允许空值,用一个定制的验证器,因为它不会被跳过:
class User extends Model {}
User.init({
age: Sequelize.INTEGER,
name: {
type: DataTypes.STRING,
allowNull: true,
validate: {
customValidator(value) {
if (value === null && this.age !== 10) {
throw new Error("name can't be null unless age is 10");
}
})
}
}
}, { sequelize });
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 基本查询
# 排序
order选项接受一个项目数组来对查询进行排序,或者使用sequelize方法。这些项目本身就是以[列,方向]的形式排列的。该列将被正确转义,方向将在有效方向的白名单中被检查(如ASC、DESC、NULLS FIRST等)。
Subtask.findAll({
order: [
// 将转义标题和验证DESC对一个有效的方向参数的列表
['title', 'DESC'],
// 按最大(年龄)降序
sequelize.fn('max', sequelize.col('age')),
// 按最大(年龄)降序
[sequelize.fn('max', sequelize.col('age')), 'DESC'],
// 将顺序由其他函数(' col1 ', 12, 'lalala') 降序
[sequelize.fn('otherfunction', sequelize.col('col1'), 12, 'lalala'), 'DESC'],
// 将使用模型名称作为关联的名称来订购关联模型的createdAt。
[Task, 'createdAt', 'DESC'],
// 将使用模型名称作为关联的名称,通过关联模型的createdAt进行排序。
[Task, Project, 'createdAt', 'DESC'],
// 排序将由一个关联模型的创建使用名称的关联
['Task', 'createdAt', 'DESC'],
// 使用关联的名称来创建嵌套的关联模型排序
['Task', 'Project', 'createdAt', 'DESC'],
// 通过使用关联对象来创建关联模型排序. (首选方法)
[Subtask.associations.Task, 'createdAt', 'DESC'],
// 通过使用关联对象的嵌套关联模型的创建排序。 (首选方法)
[Subtask.associations.Task, Task.associations.Project, 'createdAt', 'DESC'],
// 通过使用一个简单的关联对象来创建一个关联模型。
[{model: Task, as: 'Task'}, 'createdAt', 'DESC'],
// 由嵌套关联模型的createdAt创建简单关联对象。
[{model: Task, as: 'Task'}, {model: Project, as: 'Project'}, 'createdAt', 'DESC']
],
// 最大年龄降序
order: sequelize.literal('max(age) DESC'),
// 当方向被省略时,按最大年龄升序假设升序是默认的顺序
// 当方向被省略时,按年龄升序排列默认为升序
order: sequelize.random()
});
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33