在之前我们了解了 Sequelize 模块的一部分内容,那么这篇内容我们去了解一下 Sequelize 的 剩余的部分。
查找器
在查询数据的时候我们使用了findAll()
方法,除了这种方式,还可以使用findOne
、findOrCreate
和findAndCountAll
等方法。
findOne——查询单项
这个方法只返回查询到的数据的第一条,使用方法和findAll
一样。
findOrCreate——查找并创建
findOrCreate 可用于检测一个不确定是否存在的元素,如果存在则返回记录,不存在时会使用提供的默认值新建记录。
UserModel.findOrCreate({
where: { name: 'guodada' },
defaults: {
age: 23,
sex: 1,
score: 99
}
})
findAndCountAll——分页查询
处理程序成功将始终接收具有两个属性的对象:
- count - 一个整数,总数记录匹配 where 语句和关联的其它过滤器
- rows - 一个数组对象,记录在 limit 和 offset 范围内匹配 where 语句和关联的其它过滤器
const { count, rows } = await Project.findAndCountAll({
where: {
title: {
[Op.like]: 'foo%'
}
},
offset: 10,
limit: 2
});
console.log(count);//查询到的行数
console.log(rows);//具体的数据
验证 和 约束
什么是验证,在创建模型的时候,我们可以使用模型验证器,可以为模型的每个属性指定 格式/内容/继承 验证,也可以使用来手动验证实例。
sequelize.define('foo', {
bar: {
type: DataTypes.STRING,
validate: {
is: /^[a-z]+$/i, // 匹配这个 RegExp
is: ["^[a-z]+$",'i'], // 与上面相同,但是以字符串构造 RegExp
not: /^[a-z]+$/i, // 不匹配 RegExp
not: ["^[a-z]+$",'i'], // 与上面相同,但是以字符串构造 RegExp
isEmail: true, // 检查 email 格式 (foo@bar.com)
isUrl: true, // 检查 url 格式 (http://foo.com)
isIP: true, // 检查 IPv4 (129.89.23.1) 或 IPv6 格式
isIPv4: true, // 检查 IPv4 格式 (129.89.23.1)
isIPv6: true, // 检查 IPv6 格式
isAlpha: true, // 只允许字母
isAlphanumeric: true, // 将仅允许使用字母数字,因此 '_abc' 将失败
isNumeric: true, // 只允许数字
isInt: true, // 检查有效的整数
isFloat: true, // 检查有效的浮点数
isDecimal: true, // 检查任何数字
isLowercase: true, // 检查小写
isUppercase: true, // 检查大写
notNull: true, // 不允许为空
isNull: true, // 只允许为空
notEmpty: true, // 不允许空字符串
equals: 'specific value', // 仅允许 'specific value'
contains: 'foo', // 强制特定子字符串
notIn: [['foo', 'bar']], // 检查值不是这些之一
isIn: [['foo', 'bar']], // 检查值是其中之一
notContains: 'bar', // 不允许特定的子字符串
len: [2,10], // 仅允许长度在2到10之间的值
isUUID: 4, // 只允许 uuid
isDate: true, // 只允许日期字符串
isAfter: "2011-11-05", // 仅允许特定日期之后的日期字符串
isBefore: "2011-11-05", // 仅允许特定日期之前的日期字符串
max: 23, // 仅允许值 <= 23
min: 23, // 仅允许值 >= 23
isCreditCard: true, // 检查有效的信用卡号
// 自定义验证器的示例:
isEven(value) {
if (parseInt(value) % 2 !== 0) {
throw new Error('Only even values are allowed!');
}
}
isGreaterThanOtherField(value) {
if (parseInt(value) <= parseInt(this.otherField)) {
throw new Error('Bar must be greater than otherField.');
}
}
}
}
});
什么是约束,约束是在 SQL 级别定义的规则,比较常见的约束有主键约束、外简约束、唯一约束等,这些约束基本在创建模型的时候都有提到过。
预先加载
预先加载听起来是一个很高大上的名称,但是其作用就是一次查询多个模型,也可以叫多表查询。
先创建三个模型,然后创建关联
const User = sequelize.define('user', { name: DataTypes.STRING }, { timestamps: false });
const Task = sequelize.define('task', { name: DataTypes.STRING }, { timestamps: false });
const Tool = sequelize.define('tool', {
name: DataTypes.STRING,
size: DataTypes.STRING
}, { timestamps: false });
User.hasMany(Task);//给 Task表添加 Userid 外键
Task.belongsTo(User);//给 Task表添加 Userid 外键
User.hasMany(Tool, { as: 'Instruments' });//给Tool 添加 Userid 外键
const users = await User.findAll({ include: Task });
console.log(JSON.stringify(users, null, 2));
//select * from User
获取别名关联
const users = await User.findAll({
include: { model: Tool, as: 'Instruments' }
});
console.log(JSON.stringify(users, null, 2));
//SELECT `user`.`id`,`user`.`name`, `Instruments`.`id` AS`Instruments.id`,`Instruments`.`name` AS`Instruments.name`,
//`Instruments`.`size` AS `Instruments.size`,`Instruments`.`userId` AS `Instruments.userId`
//FROM `users` AS `user`INNER JOIN `tools` AS `Instruments` ON
过滤关联模型的数据
User.findAll({
include: {
model: Tool,
as: 'Instruments'
where: {
size: {
[Op.ne]: 'small'
}
}
}
});
多表相连
Foo.findAll({
include: [
{
model: Bar,
required: true
},
{
model: Baz,
where: /* ... */
},
Qux // { model: Qux } 的简写语法在这里也适用
]
})
到处为止,Sequelize 模块的内容就讲解完了,但是 Sequelize 模块还可以很多部分我并没有涉及到,大家可以通过官方API去自行了解