记录一个使用MySql函数实现查找子节点的功能实现
2017-03-10 15:06
295 查看
情景如下:
我们经常会有这样一个小功能需要去实现:当我们在查看一个树结构的分类数据时,我们希望点击树节点时,能够不仅展示当前节点关联的数据信息,还需要把此节点的所有子节点及更下层的节点所关联的数据全部能够展示出来,这是个很简单的需求
分析:
我以前一直使用的是Oracle数据库,而在oracle的查询语法中有一种很容易就可以实现:
这可以轻松实现查找出所有层次比传入id低的子节点ID集合;
但是在MySQL中是没有相应或者类似的方法,需要使用函数或者临时表之类的递归方法去实现,这就坑爹了。在网上找了许久,发现了一个比较好用的MySQL函数勉强可以使用,无奈将就用一下吧。
说明一下,上面的函数是我使用Navicat创建的,可能还有它自动创建的头申明文件之类的代码没有显示。
结果:
还是不太喜欢这种用函数过程写出来的功能,因为我现在的阶段,其实用到的数据库知识很简单就行,太复杂高深反而不太好去调试,而且这个函数也不具备通用性,因为表名是限定死的(我又尝试去让表名去作为参数传进函数,很遗憾,MySQL只会把变量名直接作为查询表名,然后告诉你表格不存在,弄了半天,未找到简单有效的解决途径,希望有数据库大牛去解决吧)。
最后我放弃了这个,选择了去在Java代码的Service层处理这种数据,虽然会比较挫,但是毕竟这种需求一般是在分类或者部门之类的目录结构中出现,数据量不会很大,索性把数据去查询出来,自己再去想怎么处理就怎么处理。
我们经常会有这样一个小功能需要去实现:当我们在查看一个树结构的分类数据时,我们希望点击树节点时,能够不仅展示当前节点关联的数据信息,还需要把此节点的所有子节点及更下层的节点所关联的数据全部能够展示出来,这是个很简单的需求
分析:
我以前一直使用的是Oracle数据库,而在oracle的查询语法中有一种很容易就可以实现:
select id from T_B_DEPT start with id=#{startId} connect by prior id= p_id
这可以轻松实现查找出所有层次比传入id低的子节点ID集合;
但是在MySQL中是没有相应或者类似的方法,需要使用函数或者临时表之类的递归方法去实现,这就坑爹了。在网上找了许久,发现了一个比较好用的MySQL函数勉强可以使用,无奈将就用一下吧。
BEGIN DECLARE sTemp VARCHAR(4000); DECLARE sTempChd VARCHAR(4000); SET sTemp = '$'; SET sTempChd = cast(startId as char); WHILE sTempChd is not NULL DO SET sTemp = CONCAT(sTemp,',',sTempChd); SELECT group_concat(id) INTO sTempChd FROM t_b_dept where FIND_IN_SET(p_id,sTempChd)>0; END WHILE; return sTemp; END
说明一下,上面的函数是我使用Navicat创建的,可能还有它自动创建的头申明文件之类的代码没有显示。
结果:
还是不太喜欢这种用函数过程写出来的功能,因为我现在的阶段,其实用到的数据库知识很简单就行,太复杂高深反而不太好去调试,而且这个函数也不具备通用性,因为表名是限定死的(我又尝试去让表名去作为参数传进函数,很遗憾,MySQL只会把变量名直接作为查询表名,然后告诉你表格不存在,弄了半天,未找到简单有效的解决途径,希望有数据库大牛去解决吧)。
最后我放弃了这个,选择了去在Java代码的Service层处理这种数据,虽然会比较挫,但是毕竟这种需求一般是在分类或者部门之类的目录结构中出现,数据量不会很大,索性把数据去查询出来,自己再去想怎么处理就怎么处理。
/** * 获得节点下所有子节点ID */ @Override public String getChildPointId(Integer startId) { String childIds = ""; //获得所有部门数据 List<HashMap<String, Object>> deptList = tbDeptMapper.selectDeptList(); //递归出所有子节点id并拼接成字符串 for(HashMap<String, Object> map : deptList){ Integer id = (Integer) map.get("id"); if(id == startId){ childIds += (id + ","); childIds = getChildId(id,childIds,deptList); } } return childIds; } private String getChildId(Integer id,String childIds, List<HashMap<String, Object>> deptList) { for(HashMap<String, Object> map : deptList){ Integer pid = (Integer) map.get("pId"); Integer cid = (Integer) map.get("id"); if(pid == id){ childIds += (cid + ","); childIds = getChildId(cid,childIds,deptList); } } return childIds; }
相关文章推荐
- 使用Android GPS api 实现一个轨迹记录的小功能
- 最近在为界面库中增加一个单独的换肤功能,自己记录下GDI渐变色的使用方法
- 使用silverlight构建一个工作流设计器(十八)-持久化数据到数据库—服务器段功能实现
- 使用NLog实现一个简单的日志记录(包含源代码)
- 使用一个黑客的小伎俩来实现discuz!邀请功能刷分
- asp.net 使用cookies或者session实现浏览历史记录功能
- 使用cookies实现浏览历史记录功能
- [原创]有相同父节点的一组子节点中只能选择一个,实现树中节点的单选功能!
- 使用一个黑客的小伎俩来实现discuz!邀请功能刷分
- CSDN博客:对于一个程序员,写程序就是实现功能,遇到具体问题,解决这个问题,并记录问题到CSDN上,从而有所提高和互相帮助。
- 使用DataList实现 加入购物车,编辑,删除,更新,取消功能。要求连一个产品表。
- 一个使用监听器模式实现的J2ME网络编程框架,包括一个简单的登录功能实现(含源代码)
- 使用cookies实现浏览历史记录功能
- 一个使用监听器模式实现的J2ME网络编程框架,包括一个简单的登录功能实现(含源代码)
- (转)使用一个下拉框或文本框+列表框的方式实现类似IE地址栏自动完成的功能
- 使用UIScrollView和UIPageControl实现一个简单的图片浏览功能
- 这是一个关于XML文档的操作管理器XMLHelper类,类中包括XML文档的创建,文档节点和属性的读取,添加,修改,删除的方法功能的实现
- 使用cookies实现浏览历史记录功能
- AsyncTask(1)一个使用AsyncTask实现简单异步刷新的功能。
- 使用pipe实现一个简单的类似tee命令的功能