需求:菜单管理-菜单排序。
菜单树返回前端之后,前端可以对树进行调整,最后再以一个新树作为参数传给后端,后端对菜单进行整体排序。
设计:父菜单下的子菜单为一组排序,不同父菜单排序互不影响。
因为要修改的内容比较多,会进行多次连接,所以可以用存储过程来减少链接次数
存储过程设计思路:因为存储过程不能接受list或者数组,所以我们将父菜单下的子菜单的id用逗号隔开,形成一个String,然后在传入父ID,在存储过程中对String切割遍历。
具体代码如下:
CREATE DEFINER=`root`@`%` PROCEDURE `sort_menu`(
IN menu_id_list VARCHAR(1024),
IN parentId VARCHAR(48)
)
BEGIN
DECLARE i INT DEFAULT 1;
SET @arraylength=1+(LENGTH(menu_id_list) - LENGTH(REPLACE(menu_id_list,',','')));
WHILE i<=@arraylength
DO
SET @result = REVERSE(SUBSTRING_INDEX(REVERSE(SUBSTRING_INDEX(menu_id_list,',',i)),',',1));
Select @result;
UPDATE `cms`.`cms_menu` SET `menu_order` = i-1, `parent_id` = parentId WHERE (`menu_id` = @result);
SET i=i+1;
END WHILE;
END
DECLARE i INT DEFAULT 1;
申明一个变量i类型是int 初始值为1;
SET @arraylength=1+(LENGTH(menu_id_list) - LENGTH(REPLACE(menu_id_list,',','')));
将menu_id_list的长度减去menu_id_list去掉逗号的长度+1就表示有多少个Id的传入
并赋值给变量@arraylength
再往下是一个循环
循环条件:i<=@arraylength
循环体:
SET @result = REVERSE(SUBSTRING_INDEX(REVERSE(SUBSTRING_INDEX(menu_id_list,',',i)),',',1));
将menu_id_list翻转两次(其实也能截取两次)
第一次截取到menu_id_list第i个逗号,翻转
第二次截图将翻转过的第1个逗号后面去除,然后翻转
然后作为要修改的条件修改数据库
比起一条一条的修改,这样有几个父菜单就修改几次会很明显有优化,但是最好的的效果是菜单不是顺序排列而是单链排列。
子菜单形成一个单链结构,每次修改菜单时前端都发一个请求,请求参数包括菜单id和修改后的兄id。
后端需要的操作是:
- 将要调整顺序的菜单(以下称之菜单A)的父Id这只为兄菜单的父Id,并将菜单A的兄Id设置成兄id
- 之前位置链会断裂,所以之前的地方也要链起来,将之前以菜单A为兄id的菜单的兄Id 设置为 菜单A之前的兄Id