Sequelize ORM 入门
前置
全局安装Sequelize CLI
npm i -g sequelize-cli
在项目目录下安装依赖
pnpm i sequelize mysql2
初始化
Step1.初始化
sequelize init
初始化后,项目目录下会生成四个目录:config
, migrations
, models
, seeders
其中config
目录是配置文件,主要用于配置数据库连接,配置分为三个模块,分别对应开发环境(development
)、测试环境(test
)以及生产环境(production
)
{
"development": {
"username": "root",
"password": "123456",
"database": "mysql",
"host": "127.0.0.1",
"dialect": "mysql",
"timezone": "+08:00"
},
"test": {
"username": "root",
"password": "123456",
"database": "mysql",
"host": "127.0.0.1",
"dialect": "mysql"
},
"production": {
"username": "root",
"password": "123456",
"database": "mysql",
"host": "127.0.0.1",
"dialect": "mysql",
"timezone": "+08:00"
}
}
migrations
是迁移文件,存放着数据库对应表的字段配置,这些文件用于新增、删除表,以及修改表字段等直接针对表的操作
seeders
是种子目录,当我们希望在表中插入默认数据或测试数据时就可以用到种子
Step2.创建模型(和迁移)
sequelize 数据库名:generate --name 表名 --attributes 字段名A:数据类型A,字段名B:数据类型B,……
运行数据库名:generate
命令,会生成一个模型文件,以及一个迁移文件,要注意的是,此命令中的表名应是单数,因为在根据迁移文件生成表时,Sequelize会自动在表名后补充一个“s”
注:此命令大小写敏感
运行命令:
sequelize model:generate --name Article --attributes title:string,content:text
之后,会在models
文件夹下生成article.js
文件,同时在migrations
文件夹下生成时间-create-article.js
,如20240201001232-create-article.js
迁移文件的形式如下,其中up
函数用于建表,down
函数用于删表(即db:migrate:undo
命令所执行的函数),迁移文件生成后,会自动添加id
, createdAt
, updatedAt
三个字段
'use strict';
/** @type {import('sequelize-cli').Migration} */
module.exports = {
async up(queryInterface, Sequelize) {
await queryInterface.createTable('Articles', { // createTable时自动补充了复数
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER
},
title: {
type: Sequelize.STRING
},
content: {
type: Sequelize.TEXT
},
createdAt: {
allowNull: false,
type: Sequelize.DATE
},
updatedAt: {
allowNull: false,
type: Sequelize.DATE
}
});
},
async down(queryInterface, Sequelize) {
await queryInterface.dropTable('Articles');
}
};
模型文件形式如下,它用于操作数据库
'use strict';
const {
Model
} = require('sequelize');
module.exports = (sequelize, DataTypes) => {
class Article extends Model {
/**
* Helper method for defining associations.
* This method is not a part of Sequelize lifecycle.
* The `models/index` file will call this method automatically.
*/
static associate(models) {
// define association here
}
}
Article.init({
title: DataTypes.STRING,
content: DataTypes.TEXT
}, {
sequelize,
modelName: 'Article',
});
return Article;
};
Step3.运行迁移
运行sequelize db:migrate
命令,Sequelize就会根据迁移文件在数据库中生成对应表,同时它也会自动生成一张SequelizeMeta
表,这张表中存放着当前已经运行过哪些迁移,当再次运行迁移时,这些运行过的迁移文件就会被跳过
Step4.种子的创建与运行
运行sequelize seed:generate --name 种子名
命令,以创建种子文件,种子名与表名、数据库名等名称并无实际关联,怎么起都可以(请注意可维护性)
命令执行后,会生成时间-种子名.js
文件,命名形式与迁移文件相似,生成之后的种子文件内容如下:
'use strict';
/** @type {import('sequelize-cli').Migration} */
module.exports = {
async up (queryInterface, Sequelize) {
/**
* Add seed commands here.
*
* Example:
* await queryInterface.bulkInsert('People', [{
* name: 'John Doe',
* isBetaMember: false
* }], {});
*/
},
async down (queryInterface, Sequelize) {
/**
* Add commands to revert seed here.
*
* Example:
* await queryInterface.bulkDelete('People', null, {});
*/
}
};
up
函数用于运行种子,down
函数用于撤销种子,这两个函数内容需要自己编写,自动生成的文件只会提供一个标准的格式,不包含任何功能性的代码
以下是一个基础的种子文件:
"use strict";
/** @type {import('sequelize-cli').Migration} */
module.exports = {
async up(queryInterface, Sequelize) {
const list = [];
for (let i = 1; i <= 50; i++) {
let time = new Date();
list.push({
name: "Article-" + i,
mobile: "15122223333",
createdAt: time,
updatedAt: time,
});
}
await queryInterface.bulkInsert("Articles", list, {}); // 向Articles表中插入数据
},
async down(queryInterface, Sequelize) {
await queryInterface.bulkDelete("Articles", null, {});
},
};
写好up
函数后,运行sequelize db:seed --seed 种子文件名
命令以执行up
函数
使用
增
const { User } = require("../../models"); // model实例
// Model.create()
await User.create({
name: '用户名-1',
mobile: '13612341234',
createdAt: new Date(),
updatedAt: new Date()
}
查
查找器
Sequelize提供了5种查找器,分别是findAll
, findAndCountAll
, findOne
, findByPk
, findOrCreate
,根据名字不难理解它们的功能。
findAll
:生成一个标准的SELECT
查询javascriptlet users = await User.findAll({ where: { name: 'User-1', }, });
findAndCountAll
:结合了findAll
和count
的便捷方法,在处理分页查询功能时非常有用,它会检索带有limit
和offset
的数据,同时也会返回与where
匹配的记录总数javascriptlet users = await User.findAndCountAll({ offset: Number((page - 1) * pageSize), limit: Number(pageSize), });
findOne
:与findAll
相似,但只提供检索到的第一个记录javascriptlet users = await User.findOne({ where: { id: 11, }, });
findByPk
:按主键检索javascriptlet user = await User.findByPk(11);
findOrCreate
:在表中检索,未检索到则创建一条新记录,在这两种情况下,它会返回检索或创建出的实例,和一个指明指示该实例是否已存在的布尔值javascriptconst [user, created] = await User.findOrCreate({ where: { username: 'sdepold' }, defaults: { job: 'Technical Lead JavaScript' } });
参数
const Sequelize = require("sequelize");
const Op = Sequelize.Op;
let users = await User.findAndCountAll({
// 条件
where: {
id: 2,
// 使用 AND
[Op.and]: [
{ id: 12 },
{ name: 'User-1' }
],
// 使用 OR
[Op.or]: [
{ id: 12 },
{ name: 'User-1' },
{ mobile: ['15166778899', '15100990099'] }
],
// 使用 LIKE
[Op.like]: [
{ name: 'User-1%'}
]
},
// 跳过多少条数据
offset: Number((page - 1) * pageSize),
// 取多少条数据
limit: Number(pageSize),
// 排序
order: [["id", "asc"]],
});
改
await User.update({ name: "Roland" }, {
where: {
id: 123
}
});
删
await User.destroy({
where: {
id: 123
}
});