您的位置:首页 > 数据库 > MySQL

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

2017-03-10 15:06 295 查看
情景如下:

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

分析:

我以前一直使用的是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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  MySQL 递归
相关文章推荐