问题描述:建立一个物料分类的树状图。实现效果如下:
框架使用的是Ztree, zTree 是一个依靠 jQuery 实现的多功能 “树插件”。(导航、左树右表)有兴趣的同学可以参考下面的链接:
http://www.treejs.cn
部分表结构如下图所示:
由parent_id和parent_ids字段确认该分类在树状结构中的位置,今天在这里就不详细描述树结构的实现了。(Ztree框架很简单,主要是需要完成表结构,相应的js代码都已经封装好了),对于parent_id和parent_ids字段,我们不难发现每个分类的parent_ids为它的父级(id为parent_id的分类)的parent_ids和父级的id的集合。我所参与的项目中分类有上千条,不可能一条一条地添加吧。首先想到地是写一个小的JAVADemo,简单的计算即可求出各个分类的parent_ids,但是我这个人比较懒,我在想既然是和数据库有关的操作,能不能直接用SQL语言来完成呢。于是乎,游标就派上了用场!
游标
游标实际上是一种能从包括多条数据记录的结果集中每次提取一条记录的机制。 游标充当指针的作用。 尽管游标能遍历结果中的所有行,但他一次只指向一行。 游标的作用就是用于对查询数据库所返回的记录进行遍历,以便进行相应的操作。
对于上述问题中需要生成每个分类的parent_ids的代码实现如下:
-- 生成所有父id;
-- 分隔标记
delimiter $$
-- 创建存储过程
create procedure testCur()
BEGIN
-- 声明变量
DECLARE cid BIGINT;
DECLARE done INT;
-- 创建游标,并设置游标所指的数据(这里设置ID不为1是因为ID为1的是总的大类)
DECLARE cur CURSOR for
SELECT id as cid from mdm_material_category where parent_id!='1' and id!='1';
-- 游标执行完,即遍历结束。设置done的值为1
DECLARE CONTINUE HANDLER for not FOUND set done=1;
-- 开启游标
open cur;
-- 执行循环
posLoop:LOOP
-- 如果done的值为1,即遍历结束,结束循环
IF done=1 THEN
LEAVE posLoop;
-- 注意,if语句需要添加END IF结束IF
END IF;
-- 从游标中取出cid
FETCH cur INTO cid;
-- 以游标中取出的cid为索引,逐行更新分类表:某分类parent_ids值为它的父分类parent_ids值和它父类的id
UPDATE mdm_material_category m1,mdm_material_category m2 SET m1.parent_ids=CONCAT(m2.parent_ids,',',m2.id)
where m1.parent_id=m2.id and m1.id=cid;
-- 关闭循环
END LOOP posLoop;
-- 关闭游标
CLOSE cur;
-- 关闭分隔标记
END $$
对于上述代码有几个需要注意的地方:
1.mysql存储过程每一句后面必须用;结尾,使用的临时字段需要在定义游标之前进行声明。
2. 在mysql中对于变量的声明(Declare)只能在存储过程中。注意分隔标记的缺少可能会导致失败。
接下来就是执行存储过程了。
CALL testCur;
删除存储过程:
DROP PROCEDURE testCur;
关于游标的使用就是如上了!谢谢您的耐心!