记录一个使用MySql函数实现查找子节点的功能实现

来源:互联网 发布:伦敦金交易数据 编辑:程序博客网 时间:2024/04/29 23:33

情景如下:

我们经常会有这样一个小功能需要去实现:当我们在查看一个树结构的分类数据时,我们希望点击树节点时,能够不仅展示当前节点关联的数据信息,还需要把此节点的所有子节点及更下层的节点所关联的数据全部能够展示出来,这是个很简单的需求

分析:

我以前一直使用的是Oracle数据库,而在oracle的查询语法中有一种很容易就可以实现:

select id from T_B_DEPT start with id=#{startId} connect by prior id= p_id
这可以轻松实现查找出所有层次比传入id低的子节点ID集合;

但是在MySQL中是没有相应或者类似的方法,需要使用函数或者临时表之类的递归方法去实现,这就坑爹了。在网上找了许久,发现了一个比较好用的MySQL函数勉强可以使用,无奈将就用一下吧。

BEGINDECLARE sTemp VARCHAR(4000);DECLARE sTempChd VARCHAR(4000);SET sTemp = '$';SET sTempChd = cast(startId as char);WHILE sTempChd is not NULL DOSET 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 */@Overridepublic 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;}

0 0