本文来介绍 Sequelize,一个基于 Node.js 的 ORM(对象关系映射)工具,并详细介绍其用法。Sequelize 用于在应用中使用 JavaScript 来操作关系型数据库,例如 MySQL、PostgreSQL 等。本文内容较多,可作为 Sequelize 的参考手册来阅读。
Sequelize 是一个基于 JavaScript 的 ORM(对象关系映射)库,用于在 Node.js 环境中与数据库进行交互。它提供了一种方便、灵活的方式来管理数据库,并将数据库表映射为对象,使开发人员可以使用面向对象的编程风格来操作数据库。
ORM(对象关系映射)是一种编程技术,用于通过将对象和数据库表之间建立映射关系,以更直观的方式进行数据库操作。Sequelize 通过将数据库记录映射为模型对象,使得开发人员可以使用 JavaScript 对象的方法和属性来进行数据库的增删改查操作,而不需要编写复杂的 SQL 查询语句。
Sequelize 支持多种数据库,包括 MySQL、PostgreSQL、SQLite 和 MSSQL 等,可以适应各种不同的项目需求。它提供了丰富的功能,包括模型定义、关联关系、事务处理、查询构建器等,可以帮助开发人员高效地进行数据库操作。
使用 Sequelize,开发人员可以轻松地进行数据库迁移、执行复杂的查询和聚合操作,并实现数据校验和验证等功能。此外,它还提供了钩子函数、事件触发和数据库连接池等功能,以优化数据库访问性能。
要使用 Sequelize 来连接 MySQL 数据库,需要进行以下步骤:
const { Sequelize } = require('sequelize');
const sequelize = new Sequelize('database', 'username', 'password', {
host: 'localhost',
dialect: 'mysql',
});
这里需要将 'database'、'username' 和 'password' 分别替换为 MySQL 数据库的名称、用户名和密码。还可以根据需要设置其他连接选项,例如 host 和 port。
const User = sequelize.define('User', {
username: {
type: DataTypes.STRING,
allowNull: false,
},
email: {
type: DataTypes.STRING,
allowNull: false,
unique: true,
validate: {
isEmail: true,
},
},
// 其他属性和选项
});
这里定义了一个名为 User 的模型,包含 username 和 email 属性。
async function createUser() {
await sequelize.sync(); // 同步模型和数据库
const user = await User.create({ username: 'John', email: 'john@cdxwcx.com' });
console.log(user.toJSON());
}
createUser().catch(console.error);
这里首先调用 sequelize.sync() 方法来同步模型和数据库,以确保模型在数据库中存在。然后使用 User.create() 方法创建一个新用户,并输出其序列化后的 JSON 数据。
这只是 Sequelize 连接 MySQL 的基本用法,你还可以使用 Sequelize 提供的其他方法来执行查询、更新、删除等操作,以及定义模型之间的关联关系。下面会详细介绍!
在 Sequelize 中,模型(Model)是一种表示数据库表结构的抽象化概念。它定义了数据表的结构和行为,包括表名、字段、关联关系、数据校验规则等。
Sequelize 模型允许通过编写模型类来操作数据库表,封装了对数据库的增删改查等操作。每个模型类对应一个数据库表,并且模型类的实例代表数据库表中的一条记录。
可以使用sequelize.define() 方法来创建模型,它用于定义和创建模型,其基本语法如下:
sequelize.define(modelName, attributes, options)
参数说明:
const { Sequelize, DataTypes } = require('sequelize');
const sequelize = new Sequelize('database', 'username', 'password');
const User = sequelize.define('User', {
id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
},
username: {
type: DataTypes.STRING,
allowNull: false,
},
email: {
type: DataTypes.STRING,
allowNull: false,
unique: true,
validate: {
isEmail: true,
},
},
createdAt: {
type: DataTypes.DATE,
allowNull: false,
defaultValue: Sequelize.literal('CURRENT_TIMESTAMP'),
},
updatedAt: {
type: DataTypes.DATE,
allowNull: false,
defaultValue: Sequelize.literal('CURRENT_TIMESTAMP'),
},
}, {
tableName: 'users',
timestamps: true,
});
// 创建用户实例
User.create({ username: 'John', email: 'john@cdxwcx.com' })
.then((user) => {
console.log(user.toJSON());
})
.catch(console.error);
这里使用 sequelize.define() 方法定义了一个名为 User 的模型。模型具有 id、username、email、createdAt 和 updatedAt 等属性。我们还指定了表名为 'users',以及启用了时间戳属性。
在 Sequelize 中,创建模型的步骤如下:
const Sequelize = require('sequelize');
const sequelize = new Sequelize('database', 'username', 'password', {
// 配置数据库连接信息
});
// 定义模型
const User = sequelize.define('User', {
name: Sequelize.STRING,
email: Sequelize.STRING,
age: Sequelize.INTEGER,
});
// 同步模型到数据库
(async () => {
try {
await sequelize.sync();
console.log('模型创建成功!');
} catch (error) {
console.error('模型创建失败:', error);
} finally {
sequelize.close(); // 关闭数据库连接
}
})();
记得在最后关闭 Sequelize 连接,避免资源泄漏。
注意,模型创建后只需调用 sequelize.sync 方法进行同步一次即可,后续对模型的修改不会自动同步到数据库。如果想要更新现有的模型定义,可以使用 Sequelize 提供的迁移工具或手动修改数据库表结构。
上面的例子只定义了字段的类型,其实还有很多属性可以定义,下面来看一个例子:
const Sequelize = require('sequelize');
const sequelize = new Sequelize('database', 'username', 'password', {
// 配置数据库连接信息
});
const User = sequelize.define('User', {
name: {
type: Sequelize.STRING,
allowNull: false,
},
email: {
type: Sequelize.STRING,
allowNull: false,
unique: true,
validate: {
isEmail: true,
},
},
age: {
type: Sequelize.INTEGER,
allowNull: false,
defaultValue: 0,
validate: {
min: 0,
},
},
});
在字段定义对象中,每个属性表示一个字段。属性的名称是字段的名称,属性的值是字段的配置。下面来分别看看这些字段值。
type 属性用于指定模型字段的数据类型。以下是一些常见的数据类型选项:
此外,Sequelize 还支持将数据类型与修饰符结合使用,以提供更丰富的数据定义选项。例如:
在 Sequelize 中,数字类型包括以下几种:
在 Sequelize 中,字符串类型有以下几种选项可供选择:
在 Sequelize 中,日期类型包括以下几种:
在 Sequelize 中,UUID 类型用于表示一个全局唯一的标识符。Sequelize 支持以下几种 UUID 类型:
allowNull 是 Sequelize 中用于定义模型字段是否允许为空的属性选项。
当 allowNull 设置为 true 时,表示该字段允许为空。这意味着在创建记录或更新记录时,可以将该字段设置为空值(null)。如果设置为 false,表示该字段不能为空。
defaultValue 用于定义模型字段默认值的属性选项。
当创建记录时,如果没有提供该字段的值,则会使用 defaultValue 属性定义的默认值。
primaryKey 是用于指定模型字段作为主键的属性选项。
主键是数据库表中的一种特殊字段,它用于唯一标识表中的每一行记录。主键字段的值在整个表中必须是唯一的,并且不能为空。通过将 primaryKey 设置为 true,可以指示 Sequelize 将该字段设置为模型的主键。
autoIncrement 是一个用于指定模型字段是否为自增字段的属性选项。
自增字段是一种特殊类型的主键,它的值会在每次插入新记录时自动递增。通常用于为每个新记录分配唯一的标识符。自增字段的常见类型为整数(例如,INTEGER)。通过将 autoIncrement 设置为 true,可以指示 Sequelize 将该字段设置为自增字段。
使用自增字段可以方便地生成唯一的标识符,而无需显式指定每个新记录的值。数据库在插入新记录时会自动递增该字段的值。这对于需要快速添加新记录并确保主键唯一性的情况非常有用。
注意,autoIncrement 属性仅对整数类型的字段有效。
unique 用于定义模型字段是否唯一的属性选项。
当将 unique 设置为 true 时,表示该字段的值必须在整个表中是唯一的。也就是说,在同一列中,每个记录都必须有一个唯一的值,不能重复。
validate 是用于定义模型字段验证规则的属性选项。
通过 validate 属性,可以定义一个包含验证规则的对象,用于验证模型字段的值是否符合指定的条件。validate 属性可以包含多个验证规则,每个规则可以是一个函数或一个对象。下面是一些常见的验证规则属性值:
这只是一些常见的验证规则,Sequelize 还提供了更多的内置验证规则。此外,你还可以定义自定义的验证函数来进行复杂的验证逻辑。
const User = sequelize.define('User', {
username: {
type: Sequelize.STRING,
allowNull: false,
validate: {
notEmpty: true,
len: [3, 20],
isAlphanumeric: true,
},
},
email: {
type: Sequelize.STRING,
allowNull: false,
validate: {
isEmail: true,
},
},
});
comment 是用于为模型字段添加注释的属性选项。
注释是对字段的描述性文本,可以提供关于字段用途、含义或其他相关信息的补充说明。注释对于理解和维护数据库结构非常有帮助。
const User = sequelize.define('User', {
username: {
type: Sequelize.STRING,
comment: '用户的用户名', // 字段注释
},
email: {
type: Sequelize.STRING,
comment: '用户的电子邮件地址', // 字段注释
},
});
field 是一个用于指定模型字段在数据库中的实际名称的属性选项。
默认情况下,Sequelize 会将模型定义中的字段名称直接映射到数据库表中对应的列名。但是,有时可能希望在数据库中使用不同的列名,这时可以使用 field 属性来指定实际的数据库列名。
const User = sequelize.define('User', {
firstName: {
type: Sequelize.STRING,
field: 'first_name', // 指定数据库对应的列名
},
lastName: {
type: Sequelize.STRING,
field: 'last_name', // 指定数据库对应的列名
},
});
在上述示例中,firstName 字段的 field 属性设置为 first_name,lastName 字段的 field 属性设置为 last_name。这将导致在数据库表中创建名为 first_name和last_name 的列。
使用 field 属性可以非常灵活地控制模型字段与数据库列的映射关系。这在需要与遗留数据库或特定数据库命名约定交互的情况下非常有用。
注意,如果不指定 field 属性,Sequelize 将默认使用与模型字段名称相同的列名。
get 字段表示一个自定义的 getter 方法。它是一个通过访问模型实例属性来获取计算值的函数。
使用 get 字段,可以定义一个自定义的 getter 方法,该方法会在访问特定属性时被调用,以便根据需要对属性进行计算、处理或转换。
const User = sequelize.define('User', {
firstName: {
type: Sequelize.STRING,
allowNull: false,
},
lastName: {
type: Sequelize.STRING,
allowNull: false,
},
fullName: {
type: Sequelize.VIRTUAL, // 虚拟属性
get() {
return `${this.firstName} ${this.lastName}`;
},
},
});
const user = User.build({
firstName: 'Alice',
lastName: 'Smith',
});
console.log(user.fullName); // 输出:Alice Smith
使用 get 字段可以方便地在访问模型属性时进行额外的计算或处理。它使得模型实例的属性具有更多的灵活性和复杂性。
set 字段表示一个自定义的 setter 方法。它允许你在设置属性值时执行一些自定义逻辑或转换。
使用 set 字段,可以定义一个自定义的 setter 方法,该方法会在设置特定属性的值时被调用,以便对该值进行处理、验证或转换。
const User = sequelize.define('User', {
fullName: {
type: Sequelize.STRING,
set(value) {
const names = value.split(' ');
this.setDataValue('firstName', names[0]);
this.setDataValue('lastName', names[1]);
},
},
});
const user = User.build();
user.fullName = 'Alice Smith';
console.log(user.firstName); // 输出:Alice
console.log(user.lastName); // 输出:Smith
当给 user.fullName 赋值时,Sequelize 将自动调用定义的 setter 方法,并进行相应的属性设置。
使用 set 字段可以方便地在设置模型属性值时执行自定义的逻辑或转换操作。它使得模型属性的赋值具有更多的灵活性和复杂性。
references 是一个模型定义中的选项,用于指定关联关系中引用的目标模型和目标属性。
当在 Sequelize 模型定义中使用 references 选项,它表示当前模型与另一个模型之间的关联关系,并指定了相关联的目标模型和目标属性。
const User = sequelize.define('User', {
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true,
},
username: {
type: Sequelize.STRING,
allowNull: false,
},
});
const Post = sequelize.define('Post', {
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true,
},
title: {
type: Sequelize.STRING,
allowNull: false,
},
userId: {
type: Sequelize.INTEGER,
references: {
model: User, // 引用的目标模型
key: 'id', // 引用的目标属性
},
},
});
这里定义了两个模型:User 和 Post。在 Post 模型的定义中,使用了 references 选项来创建一个与 User 模型的关联关系。
references 选项包含两个属性:
这意味着 Post 模型中的 userId 属性将引用 User 模型中的 id 属性作为关联。这意味着 userId 和 User 模型的 id 属性具有相同的值。
通过使用 references 选项,Sequelize 可以根据关联关系设置合适的数据库约束,并帮助你在查询中轻松处理模型之间的关联。
onDelete 是一个定义关联关系时可以设置的选项之一。它用于指定当关联模型的记录被删除时要执行的操作。
使用 onDelete 选项,可以定义在删除关联模型的记录时应该执行的操作,例如级联删除、设置为 null 或什么都不做等。
以下是一些常用的 onDelete 选项值及其含义:
const User = sequelize.define('User', {
id: {
type: DataTypes.INTEGER,
primaryKey: true
}
});
const Post = sequelize.define('Post', {
id: {
type: DataTypes.INTEGER,
primaryKey: true
},
userId: {
type: DataTypes.INTEGER,
references: {
model: User,
key: 'id'
},
onDelete: 'CASCADE' // 当关联的 User 记录被删除时,与之关联的 Post 记录也将被删除
}
});
这里定义了一个 User 模型和一个 Post 模型。在 Post 模型的定义中,我们设置了与 User 模型的关联,并在 userId 属性上使用了 onDelete: 'CASCADE' 选项。这意味着当与之关联的 User 记录被删除时,与之关联的 Post 记录也将被级联删除。
onUpdate 是一个定义关联关系时可以设置的选项之一。它用于指定当关联模型的记录被更新时要执行的操作。
使用 onUpdate 选项,可以定义在更新关联模型的记录时应该执行的操作,例如级联更新或什么都不做等。
以下是一些常用的 onUpdate 选项值及其含义:
const User = sequelize.define('User', {
id: {
type: DataTypes.INTEGER,
primaryKey: true
}
});
const Post = sequelize.define('Post', {
id: {
type: DataTypes.INTEGER,
primaryKey: true
},
userId: {
type: DataTypes.INTEGER,
references: {
model: User,
key: 'id'
},
onUpdate: 'CASCADE' // 当关联的 User 记录被更新时,与之关联的 Post 记录也将被相应地更新
}
});
这里定义了一个 User 模型和一个 Post 模型。在 Post 模型的定义中,我们设置了与 User 模型的关联,并在 userId 属性上使用了 onUpdate: 'CASCADE' 选项。这意味着当与之关联的 User 记录被更新时,与之关联的 Post 记录也将相应地进行级联更新。
模型继承是一种将一个模型继承自另一个模型的机制。这使得你可以从一个已有的模型中派生出新的模型,并继承它的属性、方法和关联关系,从而实现代码重用和模型的层次结构组织。
模型继承通过使用 sequelize.define() 方法的 options 参数来实现。在定义模型时,可以指定 options 参数中的 extend 属性,来指定该模型继承自哪个父模型。被继承的父模型称为基础(或父)模型,而继承的新模型称为派生(或子)模型。
下面来看看如何在 Sequelize 中进行模型继承:
const { Model, DataTypes } = require('sequelize');
const sequelize = new Sequelize('database', 'username', 'password');
// 定义基础模型
const BaseModel = sequelize.define('base', {
name: {
type: DataTypes.STRING,
allowNull: false,
},
// 其他属性...
});
// 定义派生模型,并继承基础模型
const DerivedModel = sequelize.define('derived', {
age: {
type: DataTypes.INTEGER,
allowNull: false,
},
// 其他属性...
}, {
extend: BaseModel,
});
// 创建派生模型的实例
DerivedModel.create({ name: 'John', age: 25 })
.then((instance) => {
console.log(instance.toJSON());
})
.catch(console.error);
这里首先定义了一个基础模型 BaseModel,它有一个名为 name 的属性。然后,定义了派生模型 DerivedModel,它继承自基础模型,并新增了一个名为 age 的属性。最后,我们使用派生模型的 create() 方法创建一个新的实例,并输出其序列化后的 JSON 数据。
通过模型继承,可以在派生模型中重用和扩展基础模型的属性、方法和关联关系,从而简化代码的编写和维护。这对于构建具有层次结构的数据模型非常有用,例如用户、管理员和超级管理员之间的继承关系。
在 Sequelize 中,修改、删除已有字段或新增字段的过程如下:
过程如下:
// 修改已有字段的数据类型和属性
await sequelize.queryInterface.changeColumn('User', 'age', {
type: Sequelize.STRING,
allowNull: true,
});
// 删除已有字段
await sequelize.queryInterface.removeColumn('User', 'age');
{
// 新增字段
await sequelize.queryInterface.addColumn('User', 'gender', {
type: Sequelize.STRING,
allowNull: true,
});
这里用 Sequelize 提供的 queryInterface 对象来执行数据库迁移操作。该对象提供了一系列方法来修改表结构。
在 Sequelize 中,修改模型定义并执行相应的迁移操作后,默认情况下数据库表不会自动同步更改。你需要显式地调用 sequelize.sync 方法来同步模型和数据库表。以下是一个在执行迁移操作后手动调用 sequelize.sync 方法的示例代码:
// 执行迁移操作...
// ...
// 手动同步模型和数据库表
await sequelize.sync();
这里使用 await sequelize.sync() 方法手动同步模型和数据库表。这将更新数据库表结构以匹配模型定义的更改。
注意,sequelize.sync() 方法会根据模型定义生成创建、修改或删除表的 SQL 命令,然后将其应用于数据库。因此,请确保在生产环境中谨慎使用该方法,并提前备份重要的数据。
如果使用 Sequelize-CLI 或其他迁移工具来管理数据库迁移,它们通常会自动处理模型与数据库表的同步操作,你不需要手动调用 sequelize.sync() 方法。但如果你手动修改了模型定义或直接使用 queryInterface 修改数据库表结构,则需要手动同步模型和数据库表。
要删除 Sequelize 中的模型,可以使用 sequelize.drop 方法。
以下是一个示例代码来删除一个名为 User 的模型:
// 删除模型
await User.drop();
注意,删除模型将会永久删除数据库表,包括其中的数据。在执行模型删除操作之前,请确保备份重要的数据。请谨慎操作删除模型,确保你的操作不会导致数据丢失或不可逆的更改。
在异步函数中执行删除操作,并在完成后输出相应的信息。最后,记得关闭 Sequelize 连接,以避免资源泄漏。
先来看看查询是一些通用查询参数。
使用 where 方法可以添加查询条件,它可以用于查询语句中的各种不同部分,如 findOne 和 findAll 等。通过 where 方法可以根据指定的条件过滤数据库中的记录。
Op 对象是 Sequelize 中用于定义各种操作符的对象。它提供了很多常用的操作符,可以在查询条件中使用。以下是一些常见的 Op 属性及其对应的操作符:
model.findAll({
where: {
age: 18
}
});
上述代码会查找 age 等于 18 的所有记录。
model.findAll({
where: {
age: {[Op.ne]: 18}
}
});
上述代码会查找 age 不等于 18 的所有记录。
model.findAll({
where: {
age: {[Op.gt]: 18}
}
});
上述代码会查找 age 大于 18 的所有记录。
model.findAll({
where: {
age: {[Op.lt]: 18}
}
});
上述代码会查找 age 小于 18 的所有记录。
model.findAll({
where: {
age: {[Op.gte]: 18}
}
});
上述代码会查找 age 大于等于 18 的所有记录。
model.findAll({
where: {
age: {[Op.lte]: 18}
}
});
上述代码会查找 age 小于等于 18 的所有记录。
model.findAll({
where: {
name: {
[Op.like]: '%John%'
}
}
});
上述代码会查找 name 字段中包含 "John" 的所有记录。
也可以使用 $like 来查询,这是 sequelize 的旧语法,建议使用新语法 [Op.like] 来查询:
model.findAll({
where: {
name: {
$like: '%John%'
}
}
});
model.findAll({
where: {
age: {[Op.between]: [18, 30]}
}
});
上述代码会查找 age 在 18 到 30 之间的所有记录。
可以使用 [Op.or] 操作符来实现查询一个字段等于 a 或 b 的操作。
const { Op } = require('sequelize');
const users = await User.findAll({
where: {
[Op.or]: [
{ name: 'a' },
{ name: 'b' },
],
},
});
这里使用 findAll 方法查找所有名字等于 'a' 或 'b' 的用户。其中,[Op.or] 表示 OR 连接操作符,将两个条件拼接成 OR 条件。
注意,在实际使用时,如果需要查询多个可能值,可以使用[Op.in]操作符,例如:
const users = await User.findAll({
where: {
name: {
[Op.in]: ['a', 'b'],
},
},
});
上述代码将会查询所有名字等于 'a' 或 'b' 的用户。
在 Sequelize 中,可以使用关联来定义模型之间的关系,例如一对一、一对多或多对多关系。当查询模型时,如果希望返回与该模型关联的其他模型的属性,就需要使用 include 选项来包含关联模型。可以根据需要轻松地从其他模型中获取相关数据,而无需单独进行额外的查询操作。
User.findAll({
include: {
model: Post,
attributes: ['title', 'content']
}
})
.then((users) => {
// 处理查询结果
users.forEach((user) => {
console.log('用户名:', user.name);
console.log('用户发布的文章:');
user.Posts.forEach((post) => {
console.log('标题:', post.title);
console.log('内容:', post.content);
});
});
})
.catch((error) => {
// 处理查询错误
});
这里使用 User 模型进行查询,通过 include 选项包含了关联的 Post 模型。然后,在 .then 回调函数中处理查询结果。每个用户对象都包含了他们的相关文章数据,可以通过访问 user.Posts 属性来获取关联的文章数据。
当在主模型上执行查询后,包含关联模型的查询实际上是在主模型查询的基础上进行的。
首先,使用主模型进行查询,获取与查询条件匹配的主模型数据。然后,在查询结果中包含的每个主模型实例上,Sequelize 将自动执行额外的查询来获取与之关联的其他模型的数据。
这种查询方式称为延迟加载或延迟关联。它的优点是只有在需要访问关联模型数据时才执行额外的查询,避免了不必要的查询开销。
在上面的示例中,当调用 User.findAll() 查询用户时,Sequelize 会从数据库获取与查询条件匹配的用户数据。然后,当访问 user.Posts 属性时,Sequelize 会自动执行另一个查询来获取该用户关联的文章数据。
在查询时包含多个关联模型,可以通过 Sequelize 的 include 选项的不同方式来实现。下面有两种常用的方法:
User.findAll({
include: [
{ model: Profile },
{ model: Post }
]
})
.then((users) => {
// 处理查询结果
users.forEach((user) => {
console.log('用户名:', user.name);
console.log('用户配置:', user.Profile);
console.log('用户文章:', user.Posts);
});
})
.catch((error) => {
// 处理查询错误
});
在上述代码中,将要包含的关联模型作为对象放入数组中,并将该数组作为 include 选项的值。这样,在查询结果中就会包含多个关联模型的数据。
User.findAll({
include: [
{
model: Profile,
include: [Category] // 在 Profile 模型中嵌套包含 Category 模型
},
{ model: Post }
]
})
.then((users) => {
// 处理查询结果
users.forEach((user) => {
console.log('用户名:', user.name);
console.log('用户配置:', user.Profile);
console.log('用户文章:', user.Posts);
console.log('用户配置的类别:', user.Profile.Category);
});
})
.catch((error) => {
// 处理查询错误
});
这里使用嵌套的方式,在其中一个关联模型的 include 选项中,再嵌套包含另一个关联模型。这样可以实现更深层次的关联查询。
通过以上方式,可以在查询时包含多个关联模型,并获取它们的数据。根据需求和模型之间的关系,可以灵活地组合和嵌套使用 include 选项来包含多个关联模型。
注意:只有在模型定义中定义了关联关系,才能在查询时包含关联模型。
可以使用 attributes 选项指定要返回的字段。示例:attributes: ['id', 'name']。它用于控制查询结果中包含哪些属性或排除哪些属性,可以接受多种形式的参数,以控制返回的属性。
以下是几种常见的 attributes 选项的用法:
注意事项:
可以使用 order 选项来指定返回结果的排序规则。示例:order: [['createdAt', 'DESC']],它表示按照 createdAt 字段进行降序排列。
在 Sequelize 中,可以通过 order 选项来指定查询结果的排序规则。排序规则由一个二维数组表示,每个子数组包含两个元素:排序字段和排序方式。排序字段可以是模型的属性名或关联模型的属性名。排序方式可以是 'ASC'(升序)或 'DESC'(降序)。
以下是order 选项常见的用法:
注意事项:
Model.findOne({
where: {
// 查询条件
status: 'active'
},
order: [['createdAt', 'DESC']]
})
.then((records) => {
// 处理查询结果
})
.catch((error) => {
// 处理查询错误
})
这里使用了 order 选项,通过 [['createdAt', 'DESC']] 指定了按照 createdAt 字段进行降序排列。
用于限制查询结果返回的记录数量,常用于分页查询。
Model.findAll({
limit: 10 // 返回最多 10 条记录
})
.then((results) => {
// 处理查询结果
})
.catch((error) => {
// 处理查询错误
});
用于设置查询结果的偏移量,从指定位置开始返回结果,常用于分页查询。这个偏移量是基于索引的,而索引是从零开始计数的。
Model.findAll({
offset: 5 // 忽略前 5 条记录
})
.then((results) => {
// 处理查询结果
})
.catch((error) => {
// 处理查询错误
});
用于对结果进行分组:按照指定的字段值进行分类归纳,将具有相同字段值的记录放在一组中。
Model.findAll({
attributes: ['age'],
group: ['age']
})
.then((results) => {
// 处理查询结果
results.forEach((group) => {
console.log('分组:');
group.forEach((record) => {
console.log('记录:', record);
});
});
})
.catch((error) => {
// 处理查询错误
});
这里使用 group 选项对 age 字段进行分组。查询结果 results 是一个数组,其中每个元素代表一个分组。对于每个分组,可以遍历内层数组 group,其中的每个元素代表该分组中的一条记录。
当设置 distinct: true 时,查询结果将会返回去重后的记录。这在某些情况下非常有用,例如获取一个字段的唯一值列表或者按照某个字段进行分组统计时。
这里使用 distinct: true 设置查询结果为去重模式,并指定了要查询的字段为 name。查询结果将只包含去重后的姓名列表。
例如,假设有一个名为 User 的模型,并且希望获取所有不重复的用户名:
const users = await User.findAll({
attributes: ['name'],
distinct: true
});
这里通过设置 distinct: true 来确保只返回不重复的用户名。查询结果将只包含唯一的、不重复的用户名。
注意,distinct 选项必须与指定的查询字段一起使用,确保只对指定的字段进行去重操作。
查询符合条件的第一条记录。
Model.findOne({
where: {
// 查询条件
id: 1
}
})
.then((record) => {
if (record) {
console.log('查询到的记录:', record.get({ plain: true }));
} else {
console.log('未找到符合条件的记录');
}
})
.catch((error) => {
// 处理查询错误
});
这个方法的返回值是一个 Sequelize Model 对象,其中包含与记录相关联的属性、方法和关系。它具有以下特性:
record.get():返回一个包含所有字段的对象,其中字段名作为键,字段值作为值。这个对象是 Sequelize 模型实例,包含与记录相关联的属性和方法。
record.get({ plain: true }):返回一个纯对象,只包含记录的原始字段和值,不包含与 Sequelize 相关的属性和方法。
获取指定字段的值:可以传递一个或多个字段名作为参数,获取特定字段的值。示例:record.get('fieldName') 或 record.get('field1', 'field2')。
排除指定字段:可以使用 { exclude: ['fieldName'] } 选项来排除指定的字段,获取除这些字段外的其他字段。示例:record.get({ exclude: ['fieldName'] })。
只获取指定字段:可以使用 { attributes: ['fieldName'] } 选项来只获取指定的字段。示例:record.get({ attributes: ['fieldName'] })。
Model.findOne({
where: {
// 查询条件
id: 1
}
})
.then((record) => {
if (record) {
const fieldValue = record.get('fieldName');
console.log('字段值:', fieldValue);
const excludedData = record.get({ exclude: ['field1', 'field2'] });
console.log('排除字段后的数据:', excludedData);
const selectedData = record.get({ attributes: ['field1', 'field2'] });
console.log('只包含指定字段的数据:', selectedData);
} else {
console.log('未找到符合条件的记录');
}
})
.catch((error) => {
// 处理查询错误
});
注意,Model.findOne 方法只返回满足查询条件的第一条记录。如果没有符合条件的记录,则返回 null。
另外,distinct: true 在某些数据库管理系统中可能会导致性能下降,因为它需要进行更多的计算来实现去重。所以在使用 distinct: true 时,要谨慎考虑其对性能的影响。
sequelize.findAll() 用于从数据库中检索所有匹配给定条件的记录。它的语法如下:
Model.findAll({
attributes: [], // 要选择的属性列表,默认为所有属性
where: {}, // 过滤条件
include: [], // 关联模型
order: [], // 排序规则
limit: 0, // 返回的最大记录数,默认为0(返回所有记录)
offset: 0, // 结果集的起始偏移量,默认为0
});
参数说明:
这个方法将返回一个Promise,当查询成功时,Promise将解析为包含所有符合条件的记录的数组。以下是一个示例:
Model.findAll({
where: {
// 查询条件
status: 'active'
}
})
.then((records) => {
if (records.length > 0) {
console.log('查询到的记录数:', records.length);
records.forEach((record) => {
const data = record.get();
console.log('记录数据:', data);
});
} else {
console.log('未找到符合条件的记录');
}
})
.catch((error) => {
// 处理查询错误
});
注意,如果没有查询到符合条件的记录,返回的数组将为空。
根据主键值查询记录,它的语法如下:
Model.findByPk(id, options);
参数说明:
下面来看一个例子,通过主键值来获取特定的用户记录:
const user = await User.findByPk(1);
console.log(user);
上述代码将查询主键值为 1 的用户记录,并将结果保存在 user 变量中。如果找到匹配的记录,则 user 将是一个包含该记录的对象。否则,user 将是 null。
如果要通过主键值获取多个记录,可以传入一个数组作为 id 参数,如:
const users = await User.findByPk([1, 2, 3]);
console.log(users);
上述代码将查询主键值为 1、2 和 3 的用户记录,并将结果保存在 users 变量中,它将是一个包含这些记录的数组。
findByPk 也可以与其他查询配置选项一起使用,例如关联模型、选择属性等。可以在 options 参数中指定这些额外的配置选项。
注意:findByPk 方法返回一个 Promise,在查询成功时解析为匹配的记录(或记录数组),在查询失败时拒绝为错误对象。因此,需要使用 await 或 .then() 来处理查询结果或捕获错误。
在 Sequelize 中,主键值是指用于唯一标识数据库表中每个记录的列或属性。主键值在表中具有唯一性,没有重复的值,且不能为空。在 Sequelize 模型定义中,可以通过 primaryKey: true 来将某个属性指定为主键。例如:
const User = sequelize.define('User', {
id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true
},
name: DataTypes.STRING,
email: DataTypes.STRING
});
在上述例子中,id 属性被指定为主键。它的类型为整数(INTEGER),并且设置了 primaryKey: true 表示该属性是主键。此外,还可以使用 autoIncrement: true 来指定该主键自动增长,以便在插入新记录时自动生成唯一的主键值。
当使用 findByPk、update、destroy 等方法时,通常会使用主键值来准确定位要操作的记录。通过提供正确的主键值,Sequelize 可以根据主键来查询、更新或删除相应的记录。
findOrCreate 用于根据指定条件查找数据库中的记录,如果找到匹配的记录,则返回该记录;如果找不到匹配的记录,则创建一个新的记录并返回。它的语法如下:
Model.findOrCreate({
where: { ... },
defaults: { ... },
...
});
参数说明:
使用 findOrCreate 方法时,Sequelize 首先根据 where 条件尝试在数据库中查找符合条件的记录。如果找到匹配的记录,则返回该记录作为结果。
如果没有找到匹配的记录,则使用 defaults 指定的默认值创建一个新的记录,并返回该新记录作为结果。默认值将应用于新创建的记录的属性。
例如,假设有一个名为 User 的模型表示用户表,其中 email 是唯一的:
const User = sequelize.define('User', {
name: DataTypes.STRING,
email: {
type: DataTypes.STRING,
unique: true
}
});
现在想根据邮箱查找用户记录,如果找到则返回该记录,如果找不到则创建一个新用户记录。可以使用 findOrCreate 方法:
const [user, created] = await User.findOrCreate({
where: { email: 'example@cdxwcx.com' },
defaults: { name: 'John Doe' }
});
console.log(user); // 匹配的记录或新创建的记录
console.log(created); // 表示是否新创建了记录的布尔值
上述代码将根据指定的邮箱查找用户记录,如果找到匹配的记录,则返回该记录。如果没有找到匹配的记录,则创建一个新的记录,并返回新创建的记录。
findOrCreate 方法返回一个包含两个元素的数组:第一个元素是匹配的记录(已存在或新创建),第二个元素是一个布尔值,表示是否新创建了记录。
如果有多个符合条件的记录,findOrCreate 方法仅返回匹配的第一个记录。它不会返回所有符合条件的记录。
findAndCountAll 用于查找满足指定条件的所有记录,并返回满足条件的记录数组和记录总数。它的语法如下:
Model.findAndCountAll({
where: { ... },
include: [ ... ],
offset: ...,
limit: ...,
order: [...],
...
});
参数说明:
使用 findAndCountAll 方法时,Sequelize 将根据指定的条件在数据库中查找符合条件的所有记录,并同时返回满足条件的记录数组和记录总数。
const { count, rows } = await User.findAndCountAll({
where: { age: 25 },
include: [Post],
offset: 0,
limit: 10,
order: [['createdAt', 'DESC']]
});
console.log(count); // 符合条件的记录总数
console.log(rows); // 符合条件的记录数组
在上述代码中,findAndCountAll 方法将根据年龄为 25 的条件在数据库中查找用户记录,并返回满足条件的记录总数和记录数组。include 参数用于指定要关联的 Post 模型。
findAndCountAll 方法返回的结果是一个包含 count 和 rows 属性的对象。count 表示符合条件的记录总数,rows 表示符合条件的记录数组。
使用 findAndCountAll 方法可以方便地获取满足条件的记录总数以及相应的记录数组,用于实现分页和其他结果统计的需求。
可以使用 count 方法来获取满足指定条件的记录数。它的语法如下:
Model.count({
where: { ... },
...
});
参数说明:
使用 count 方法时,Sequelize 将根据指定的条件在数据库中计算符合条件的记录数,并返回该记录数。
const count = await User.count({
where: { age: 25 }
});
console.log(count); // 符合条件的记录数
在上述代码中,count 方法将根据年龄为 25 的条件在数据库中计算符合条件的用户记录数,并将其返回。该方法返回的结果将是一个表示符合条件的记录数的整数值。
通过使用 count 方法,可以方便地获取满足条件的记录数,用于进行结果统计、分页计算或其他相关处理。
可以使用 min、max 和 sum 方法来进行最小值、最大值和求和计算。
这些方法可以通过调用模型的静态方法来实现,具体语法如下:
Model.min('column', {
where: { ... },
...
});
Model.max('column', {
where: { ... },
...
});
Model.sum('column', {
where: { ... },
...
});
参数说明:
const minValue = await Model.min('column', {
where: { ... }
});
const maxValue = await Model.max('column', {
where: { ... }
});
const sumValue = await Model.sum('column', {
where: { ... }
});
console.log(minValue); // 最小值
console.log(maxValue); // 最大值
console.log(sumValue); // 总和
注意,这些方法将返回一个 Promise 对象,需要使用 await 或 .then() 来获取计算结果。
create() 方法用于在数据库中创建一个新的记录。它是 Sequelize 模型的一个实例方法,可以通过模型对象调用。
const newUser = await User.create({
name: 'John Doe',
email: 'john.doe@cdxwcx.com',
age: 25,
});
使用 User.create() 方法创建一个名为 User 的新记录。通过传递一个包含属性和值的对象参数,指定要创建的记录的字段值。调用 create()方法会将新记录插入到与模型关联的数据库表中,并返回一个表示新记录的模型实例。
注意,create() 方法返回的是一个 Promise 对象,因此可以使用 await 关键字来等待创建操作的结果。如果创建成功,将返回包含新记录数据的模型实例;如果创建失败,将抛出一个异常。
create() 方法可以用于创建单个记录,也可以用于批量创建多条记录。如果想要批量创建多条记录,可以将一个包含多个对象的数组传递给 create() 方法。
const newUsers = await User.create([
{
name: 'John Doe',
email: 'john.doe@cdxwcx.com',
age: 25,
},
{
name: 'Jane Smith',
email: 'jane.smith@cdxwcx.com',
age: 30,
},
]);
要批量添加数据,可以使用 Model.bulkCreate() 方法。bulkCreate() 方法接受一个数组作为参数,每个数组元素都表示要创建的记录。
const newUsers = await User.bulkCreate([
{
name: 'John Doe',
email: 'john.doe@cdxwcx.com',
age: 25,
},
{
name: 'Jane Smith',
email: 'jane.smith@cdxwcx.com',
age: 30,
},
// 可以继续添加更多对象...
]);
这里定义了一个 users 数组,其中包含要添加到数据库的多个对象,每个对象表示一条记录。然后,调用 User.bulkCreate() 方法,并传递 users 数组作为参数,以批量添加这些记录。
bulkCreate() 方法将会将数组中的每个对象插入到与模型关联的数据库表中,并返回一个包含新记录的模型实例数组。可以根据实际需求在 users 数组中添加任意数量的对象,以批量添加相应数量的记录。
bulkCreate() 和 create() 方法都可以用于创建多条数据,但它们之间有一些区别:
综上所述,对于需要创建大量数据的情况,推荐使用 bulkCreate() 方法,以获得更好的性能。但在某些情况下,例如需要在每次创建记录时进行自定义操作或错误处理时,可以选择使用 create() 方法。
可以使用 update 方法来更新数据库中的记录。它的语法如下:
Model.update(values, {
where: { ... },
...
});
参数说明:
使用 update 方法时,Sequelize 将根据指定的条件在数据库中查找符合条件的记录,并将相应的属性更新为指定的新值。
const result = await User.update(
{ age: 30, status: 'active' },
{
where: { id: 1 }
}
);
console.log(result); // 更新结果
在上述代码中,update 方法将会将 id 属性为 1 的用户记录的 age 和 status 属性更新为新的值。
注意,update 方法返回一个表示更新结果的数组。该数组的第一个元素表示更新的行数,第二个元素表示影响的行数。
const updatedRows = result[0];
const affectedRows = result[1];
console.log(updatedRows); // 更新的行数
console.log(affectedRows); // 影响的行数
通过使用 update 方法,可以方便地更新满足条件的记录,并可以灵活配置要更新的属性和值。
注意,update 方法只能更新单条记录。如果想要更新多条数据,可以借助 Promise.all 来实现:
// 查找需要更新的数据
const usersToUpdate = await User.findAll({ where: { status: 'active' } });
// 更新数据
await Promise.all(usersToUpdate.map(user => {
return user.update(
{ status: 'inactive' } // 更新的字段和值
);
}));
在 Sequelize 中,可以使用 destroy 方法来删除数据库中的记录。它的语法如下:
Model.destroy({
where: { ... },
...
});
参数说明:
使用 destroy 方法时,Sequelize 将根据指定的条件在数据库中查找符合条件的记录,并将其从数据库中删除。<
网页题目:学会Sequelize,让你操作数据更丝滑!
标题链接:http://www.shufengxianlan.com/qtweb/news10/251760.html
网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联