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

情景如下:

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

分析:

我以前一直使用的是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;
	}



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值