1、Sequelize与Sequelize入门
可以查看Sequelize 中文文档:https://www.sequelize.com.cn/
以及结合下面的代码 进行学习。
1、初始化工作
在node项目中进行下面的操作。即当前目前下存在package.json。
如果没有就先 node init --yes ,然后再进行以下操作
1、yarn add sequelize -cli -g #jsequelize脚手架。可以局部安装,也可以全局安装
2、Yarn add sequelize
3、Yarn add mysql2
4、sequelize init #初始化sequelize
5、【可选】修改上一步所生成的config目录下的config.json。写上需要创建的数据库名称,然后 执行 sequelize db:create --charset=”utf8mb4”。#此时会帮你自动创建数据库。当然也可以手动创建数据库。
6、Sequelize model:generate --name Article --attributes title:string,content:text,author_id:bigint #自动创建模型文件和迁移文件。此命令是创建一个Article的Model(类似java后端的domian和DAO的结合体) 和 迁移文件(可通过此文件中定义的字段、以及字段类型详细,可用于系统帮我们创建 数据库的表)
Model文件夹中的article.js文件(模型文件)
注:默认系统会自动为我们创建 id、updateAt、和createAt 字段。
'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,
author_id: DataTypes.BIGINT
}, {
sequelize,
modelName: 'Article',
});
return Article;
};
Migrate文件夹中的article.js文件(迁移文件)
'use strict';
module.exports = {
up: async (queryInterface, Sequelize) => {
await queryInterface.createTable('Articles', {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER
},
title: {
type: Sequelize.STRING
},
content: {
type: Sequelize.TEXT
},
author_id: {
type: Sequelize.INTEGER
},
createdAt: {
allowNull: false,
type: Sequelize.DATE
},
updatedAt: {
allowNull: false,
type: Sequelize.DATE
}
});
},
down: async (queryInterface, Sequelize) => {
await queryInterface.dropTable('Articles');
}
};
7、sequelize db:migrate #将迁移文件里定义的字段及字段信息 转为 数据库的表。即为我们自动生成mysql的表。
8、sequelize seed:generate --name article #生成article.js种子文件,可以在种子文件中写表的测试数据,后面可将种子文件里的测试数据 导入到 数据库的表中作为表数据
seeders文件夹中的article.js文件
'use strict';
module.exports = {
up: async (queryInterface, Sequelize) => {
await queryInterface.bulkInsert('articles', [{ #数据库的表名称
title: '卢本伟开挂',
content: "这里是内容11。。。。。。",
author_id: 10,
updatedAt: new Date(),
createdAt: new Date()
},{
title: '奥运会来了。。。',
content: "这里是内容22。。。。。。",
author_id: 10,
updatedAt: new Date(),
createdAt: new Date()
},{
title: '新年到了。。。',
content: "这里是内容33。。。。。。",
author_id: 10,
updatedAt: new Date(),
createdAt: new Date()
}], {});
},
down: async (queryInterface, Sequelize) => {
/**
* Add commands to revert seed here.
*
* Example:
* await queryInterface.bulkDelete('People', null, {});
*/
}
};
9、sequelize db:seed:all #将seeders文件夹里的所有种子文件里的测试数据 导入 到数据库表中。
2、基本的CRUD操作
根据Article模型查询articles表中的所有数据
注意:sequelize操作mysql基本都是异步的,返回的是Promise对象。如果不使用await,那么这里的articleList就接收不到数据,即拿到的是null。
Await就是 阻塞等待该异步操作的完成,俗话就是让异步操作变成同步操作。如果方法内使用了 await,那么需要在方法外面声明 async。Await和async是搭配使用。
当然也可以使用下面的方法(ES6的解构)
最终结果
入门的CRUD源代码如下
const express = require('express');
const router = express.Router();
// const models = require('../models')
const {
Article
} = require('../models')
const sequelize = require('sequelize');
const {
where
} = require('sequelize');
//查询所有
router.get("/findAll", async (req, res) => {
// const articlelist = await models.Article.findAll()
const articlelist = await Article.findAll()
res.json(articlelist)
})
//排序与分页
router.get("/findPage", async (req, res) => {
// const articlelist = await models.Article.findAll()
const page = 2 //页号
const size = 3 //页大小
const articlelist = await Article.findAll({
order: [
['id','desc'] //根据 id 倒叙
],
offset: (page-1)*3, //offset 偏移量,说白就是从跳过前面多少跳记录。计算方式为(age-1)*size
limit: size
})
res.json(articlelist)
})
//单表条件查询
router.get("/findByConditaion1", async (req, res) => {
// const articlelist = await models.Article.findAll()
const articlelist = await Article.findAll({
attributes: [ //需要显示的字段
'id', 'title' //可以通过sequelize.fn调用mysql的各种函数。fn(函数名,...参数)。注:sequelize.col('列名') 和 参数值 都属于 “参数”
// [sequelize.fn('SUM',sequelize.col('id')),'idSum'], //等价 SUM(id) as idSum
, [sequelize.fn('char_length', sequelize.col('title')), 'titleLength'] //等价 char_length(`title`) AS `titleLength`
// ,[sequelize.fn('concat', '前缀 --- ', sequelize.col('id'), ' ---后缀'),'concatId'] //等价 concat('前缀 ---',id, ' ---后缀')
],
where: {
// id: 2, // id = 2
// id: {
// [sequelize.Op.gt]: 2 // id > 2
// },
// id: [2, 3], // id in(2,3)
// title: {
// [sequelize.Op.like]: '%新年%' // title like '%新年%'
// },
// [sequelize.Op.or]: [ // id = 2 or id = 3
// {id: 2},
// {id: 3}
// ]
// [sequelize.Op.or]:[ // title like '卢本伟%' or id = 3
// {
// title: {
// [sequelize.Op.like]: '卢本伟%'
// }
// },
// {id: 3}
// ]
}
})
res.json(articlelist)
})
//新增记录
router.post("/", (req, res) => {
const body = req.body
//body 内容形如 {title:xxx,content:xxx}
Article.create(body, {
fields: ['title'] //fields 指定插入列。即只插入title(除了系统的id和updateTime、createTime)
})
res.json({
code: 1000,
msg: "新增记录成功"
})
})
//更新记录
router.put("/:id", (req, res) => {
console.log(req.params.id)
Article.update({
title: '222被更新的标题' //需要被更新的字段
}, {
where: { //筛选出需要被的记录
id: req.params.id
}
})
res.json({
code: 1000,
msg: "更新记录成功"
})
})
//删除记录
router.delete('/:id', async (req, res) => {
const id = req.params.id
await Article.destroy({
where: { //这里的where 和什么条件的where一样,可以使用各种复杂筛选,然后再进行删除
id : id
}
})
res.json({
code: 1000,
msg: "删除记录成功"
})
})
module.exports = router
`
3、多表关联操作。
我们先生成一个 tb_user表,其中user 和 articles是一对多的关系,外键是article表的author_id字段是外键。
1、先用命令生成 user表的的模型和迁移文件。
sequelize model:generate --name User --attributes username:string,age:integer
生成的迁移文件为:20210131125134-create-user.js
2、然后再对指定的迁移文件 进行表结构迁移,即让程序为我们自动创建user表。
db:migrate 20210131125134-create-user.js
**3、生成种子文件。**可以让我们在种子文件里面写users表的静态数据
sequelize seed:generate --name user
4、在种子文件里编写静态数据
5、指定 将上面的users种子文件的数据用命令方式 导入 到 users表中。
sequelize db:seed --seed 20210131131133-user
6、在User模型关系中设置 和 Article的关系,以及配置外键,告诉系统,两个表是通过什么字段进行关联的。
7、代码测试
8、结果
如果觉得别名不想要Articles,也可以在模型中自定义别名。如下图