引言
递归查询,本身实现上和Sequelize
没有太大的关系,但是这里还是作为单独一讲,主要是日常项目中遇到的也非常多。
案例:多层级菜单
建表
菜单表,通过id
和pid
,知道每个菜单父级id
是谁,这样就形成了递归,一层一层寻找,只到没有没有为止。
举例:
(1)第一次找pid=0
的菜单,这样就返回了所有最高级的父级
(2)第二次,根据第一次的结果id
,找到他们下属的一级菜单
…
model配置
新建 db/model/menu.js
,配置如下:
/**
* 菜单表
*/
var Sequelize = require('sequelize');
var {sequelize} = require('../sequelize.js');
var menu = sequelize.define('menu',{
id: {
type: Sequelize.BIGINT(20),
primaryKey: true,
allowNull: false,
unique: true,
autoIncrement: true
},
pid: Sequelize.STRING(20), // 父级
name: Sequelize.STRING(255), // 名字
create_time: Sequelize.DATE,
update_time: Sequelize.DATE
},{
timestamps: false,
freezeTableName: true
});
module.exports = menu;
递归查询
router/user.js
router.get('tree', async (req, res) => {
const params = req.body;
let getNeedsTree = async function(){
let rootNeeds = await menuDB.findAll({
raw: true,
where: {
pid: 0
}
})
rootNeeds = await getChildNeeds(rootNeeds);
return rootNeeds;
}
let getChildNeeds = async function(rootNeeds){
let expendPromise = [];
rootNeeds.forEach(item => {
expendPromise.push(menuDB.findAll({
raw: true,
where: {
pid: item.id
}
}))
})
let child = await Promise.all(expendPromise);
for(let [idx , item] of child.entries()){
if(item.length > 0){
item = await getChildNeeds(item);
}
rootNeeds[idx].children = item;
}
return rootNeeds;
}
let data = await getNeedsTree()
res.send({
code: 200,
data: data
})
})
返回数据太多,咱们把日期去掉,还记得用什么属性吗?
attributes: {
exclude: ['create_time', 'update_time']
},
SELECT `id`, `pid`, `name` FROM `menu` AS `menu` WHERE `menu`.`pid` = 0;
SELECT `id`, `pid`, `name` FROM `menu` AS `menu` WHERE `menu`.`pid` = 1;
SELECT `id`, `pid`, `name` FROM `menu` AS `menu` WHERE `menu`.`pid` = 4;
SELECT `id`, `pid`, `name` FROM `menu` AS `menu` WHERE `menu`.`pid` = 2;
SELECT `id`, `pid`, `name` FROM `menu` AS `menu` WHERE `menu`.`pid` = 3;
SELECT `id`, `pid`, `name` FROM `menu` AS `menu` WHERE `menu`.`pid` = 5;
SELECT `id`, `pid`, `name` FROM `menu` AS `menu` WHERE `menu`.`pid` = 6;
SELECT `id`, `pid`, `name` FROM `menu` AS `menu` WHERE `menu`.`pid` = 7;
SELECT `id`, `pid`, `name` FROM `menu` AS `menu` WHERE `menu`.`pid` = 8;
这是sql执行次数,有多少个菜单就执行多少次
总结
本专栏,大家应该多多少少都有所收获。希望前端同学们都可以对后台业务有一定的了解,能独立完成从前端到后台一套业务开发,成为一名优秀的全栈工程师。
谢谢大家支持!
正文结束
Ctrl + Enter