引言

递归查询,本身实现上和Sequelize没有太大的关系,但是这里还是作为单独一讲,主要是日常项目中遇到的也非常多。

案例:多层级菜单

建表


菜单表,通过idpid,知道每个菜单父级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执行次数,有多少个菜单就执行多少次

总结

本专栏,大家应该多多少少都有所收获。希望前端同学们都可以对后台业务有一定的了解,能独立完成从前端到后台一套业务开发,成为一名优秀的全栈工程师。

谢谢大家支持!