一、安装sequelize-cli脚手架
npm i -g sequelize-cli
// 安装sequelize mysql2
npm i sequelize mysql2
文件或目录 | 说明 |
---|---|
config/config.js | 数据库链接配置 |
migrations | 迁移文件 (创建修改表) |
models | 模型文件 |
seeders | 种子文件 |
初始化
sequelize init
修改config.json文件
development:本地环境
test:测试环境
production:线上环境
username: 数据库用户名
password:数据库密码
database:数据库名
dialect:这里可以改成任意一种关系型数据库
timezone: ‘+08:00’ 这里是东八区,默认为0时区
pool: { 使用连接池
max: 5,
min: 0,
acquire: 30000,
idle: 10000,
},
{
"development": {
"username": "root",
"password": "xiewei",
"database": "test",
"host": "127.0.0.1",
"dialect": "mysql"
},
"test": {
"username": "root",
"password": null,
"database": "database_test",
"host": "127.0.0.1",
"dialect": "mysql"
},
"production": {
"username": "root",
"password": null,
"database": "database_production",
"host": "127.0.0.1",
"dialect": "mysql"
}
}
通过sequelize-cil 实现创建表
步骤 | 命令 | 说明 |
---|---|---|
第一步 | sequelize model:generate --name 模型名 --attributes 字段设置 | 建模型和迁移文件 |
第二步 | 人工处理 | 根据需求调整迁移文件 |
第三步 | sequelize db:migrate | 运行迁移文件,生成数据表 |
第四步 | sequelize seed:generate --name 表名 | 新建种子文件 |
第五步 | 人工处理 | 生成自己想要的文件 |
第六步 | sequelize db:seed --seed 种子文件名 | 运行种子文件,将数据生成到数据库 |
其他 | sequelize migration:create --name 文件名 | 在镜像中新增字段 |
1.命令行操作
sequelize model:generate:生成模型及其迁移
name: 模型名 建议大写必须单数
会在数据库生成articles
表
attributes:字段设置
sequelize model:generate --name Article --attributes title:string,content:text;
2.会自动在migrations目录下
生成20241211080006-create-article
当前时间下的js文件
3.运行迁移 使其可以在mysql数据库中增加表
sequelize db:migrate
多出来一个sequelizemeta表 用来记录已经跑过的哪些迁移防止重复迁移
4.插入数据
生成种子文件
sequelize seed:generate --name articie
创建100个数据
bulkInsert(“表名”, 数据, {配置参数});
"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
* }], {});
*/
const articles = [];
const counts = 100;
for (let i = 1; i <= counts; i++) {
const article = {
title: `文章的标题 ${i}`,
content: `文章的内容 ${i}`,
createdAt: new Date(),
updatedAt: new Date(),
};
articles.push(article);
}
await queryInterface.bulkInsert("articles", articles, {});
},
async down(queryInterface, Sequelize) {
await queryInterface.bulkDelete("articles", null, {});
/**
* Add commands to revert seed here.
*
* Example:
* await queryInterface.bulkDelete('People', null, {});
*/
},
};
运行文件生成数据
xxx-article:种子文件名
sequelize db:seed --seed xxx-article
二、查询
1.在正确的路由页面
引入模型
/router/article.js
const { Article } = require("../../models");
具体代码
const express = require("express");
const router = express.Router();
const { Op } = require("sequelize");
const { Article } = require("../../models");
// 必须用async await 才能获取到数据
router.get("/article", async function (req, res, next) {
try {
const query = req.query;
// 分页查询
// 当前是第几页,如果不传,默认第一页
const currentPage = Math.abs(Number(query.currentPage)) || 1;
// 每页显示多少条数据,如果不传,默认显示10条
const pageSize = Math.abs(Number(query.pageSize)) || 10;
// 从第几个索引开始查找
const offset = (currentPage - 1) * pageSize;
// 排序
const condition = {
order: [["id", "desc"]],
limit: pageSize, // limit 显示数量
offset, // 从第几个索引开始
};
// 模糊查询
if (query.title) {
condition.where = {
title: {
// LIKE 模糊查找 eq 精确查找
[Op.like]: `%${query.title}%`,
},
};
}
// findAndCountAll异步操作
const { count, rows } = await Article.findAndCountAll(condition);
res.json({
status: 200,
message: "查询成功",
data: {
articles: rows,
pagination: {
total: count,
currentPage,
pageSize,
},
},
});
} catch (err) {
res.json({ status: 1064, message: "查询失败", errors: [err.message] });
}
});
sequelize操作
模糊查询(需在文章头部引入Op对象)
const { Op } = require(“sequelize”);
1.查全部数据
findAll()
2.差主键
findByPk(主键值)
3.插入语句
create(参数)
4.删除:找到要删除的数据 执行destroy()
const articles = await Article.findByPk(id);
await articles.destroy();
5.更新:找到要删除的数据 执行update(参数)
const articles = await Article.findByPk(id);
await articles.update(req.body);
6.负责语句查询: 直接用query + sql语法
const [results] = await sequelize.query("SELECT DATE_FORMAT(`createdAt`, '%Y-%m') AS `month`, COUNT(*) AS `value` FROM `Users` GROUP BY `month` ORDER BY `month` ASC");
7.分页、排序、模糊查询
const query = req.query;
// 分页查询
// 当前是第几页,如果不传,默认第一页
const currentPage = Math.abs(Number(query.currentPage)) || 1;
// 每页显示多少条数据,如果不传,默认显示10条
const pageSize = Math.abs(Number(query.pageSize)) || 10;
// 从第几个索引开始查找
const offset = (currentPage - 1) * pageSize;
// 排序
const condition = {
order: [["id", "desc"]],
limit: pageSize, // limit 显示数量
offset, // 从第几个索引开始
};
// 模糊查询
if (query.title) {
condition.where = {
title: {
[Op.like]: `%${query.title}%`,
},
};
}
// findAndCountAll异步操作 count:总查询条数 rows 查询的结果
const { count, rows } = await Article.findAndCountAll(condition);
res.json({
status: 200,
message: "查询成功",
data: {
articles: rows,
pagination: {
total: count,
currentPage,
pageSize,
},
},
});
3、增加验证/models/article.js
具体验证规则sequelize验证与约束
"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: {
type: DataTypes.STRING,
// allowNull 必须为false 才可以自定义验证
allowNull: false,
validate: {
notNull: {
mag: "标题必须存在",
},
notEmpty: {
msg: "标题不能为空",
},
len: {
args: [2, 45],
msg: "标题长度需要在2-45个字符之间",
},
// 唯一校验
async isUnique(value) {
const titles = await Article.findOne({ where: { title: value } });
if (titles ) {
throw new Error("标题已存在");
}
},
},
},
rank: {
type: DataTypes.INTEGER,
isInt: { msg: "排序必须为整数" },
notEmpty: { msg: "必须不会空" },
notNull: { msg: "必须存在" },
// 自定义
isPositive(value) {
if (value <= 0) {
throw new Error("排序必须是正整数");
}
},
},
content: DataTypes.TEXT,
},
{
sequelize,
modelName: "Article",
}
);
return Article;
};
三、索引的添加queryInterface.addIndex
"use strict";
/** @type {import('sequelize-cli').Migration} */
module.exports = {
async up(queryInterface, Sequelize) {
await queryInterface.createTable("users", {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER.UNSIGNED,
},
avatar: {
type: Sequelize.STRING,
},
username: {
type: Sequelize.STRING,
},
nickname: {
type: Sequelize.STRING,
},
email: {
type: Sequelize.STRING,
},
sex: {
type: Sequelize.STRING,
},
birthday: {
type: Sequelize.DATE,
},
city: {
type: Sequelize.STRING,
},
company: {
type: Sequelize.STRING,
},
profession: {
type: Sequelize.STRING,
},
workType: {
type: Sequelize.STRING,
},
introduce: {
type: Sequelize.STRING,
},
role: {
type: Sequelize.TINYINT.UNSIGNED,
},
createdAt: {
allowNull: false,
type: Sequelize.DATE,
},
updatedAt: {
allowNull: false,
type: Sequelize.DATE,
},
});
await queryInterface.addIndex("users", {
fields: ["email"], // 要添加的索引字段
unique: true, // 是否唯一索引
});
await queryInterface.addIndex("users", {
fields: ["username"],
unique: true,
});
await queryInterface.addIndex("users", {
fields: ["role"],
unique: true,
});
},
async down(queryInterface, Sequelize) {
await queryInterface.dropTable("users");
},
};
三、新增表字段
1.在user表中新增phone字段
addColumn:新增
changeColumn:修改
sequelize migration:create --name add-phone-to-user
"use strict";
/** @type {import('sequelize-cli').Migration} */
module.exports = {
async up(queryInterface, Sequelize) {
// user 表中,新增phone字段
await queryInterface.addColumn("users", "password", {
type: Sequelize.STRING,
});
},
async down(queryInterface, Sequelize) {
await queryInterface.removeColumn("users", "password");
},
};
2.运行迁移命令
sequelize db:migrate
3.在user模型中增加校验
对密码加密
1.安装
npm i bcryptjs
2.使用
models/user.js文件中
"use strict";
const { Model } = require("sequelize");
// 引入
const bcryptjs = require("bcryptjs");
// 部分代码
password: {
type: DataTypes.STRING,
allowNull: false,
validate: {
notNull: { msg: "密码必须存在" },
notEmpty: { msg: "密码不能为空" },
},
set(value) {
if (value.length >= 6 && value.length <= 45) {
//加密
this.setDataValue("password", bcryptjs.hashSync(value, 10));
} else {
throw new Error("密码必须是6-45之间");
}
},
},