用mysql存储过程代替递归查询

查询此表某个id=4028ab535e370cd7015e37835f52014b(公司1)下的所有数据

正常情况下,我们采用递归算法查询,如下

public void findCorpcompanyListByParentId(List<UapcompanyVo> vos,String parentId){
		UapcompanyParam param = new UapcompanyParam();
		param.setParentid(parentId);
		List<Uapcompany> companyList = uapcompanyDao.finduapcompanyList(param);
		UapcompanyVo uapcompanyVo = null;
		for(Uapcompany uapcompany : companyList){
			uapcompanyVo = new UapcompanyVo();
			uapcompanyVo = new UapcompanyVo();
			uapcompanyVo.setId(uapcompany.getId());
			uapcompanyVo.setName(uapcompany.getName());
			uapcompanyVo.setParentid(uapcompany.getParentid());
			vos.add(uapcompanyVo);
			this.findCorpcompanyListByParentId(vos, uapcompany.getParentid());
		}
}

递归查询也能实现该需求,但是这样有两个缺点:一,性能很差 ,因为每递归一次至少调用一次数据链接;二,如果数据量很大的话,可能会导致溢出,当然可以修改虚拟机参数,不过这也是治标不治本的方法

接下来,我们看一下存储过程实现查询:

选择函数-->右键-->选择新建函数

选择过程

添加入参参数,如下图所示

完成,如下图所示

在begin end区域编写存储过程内容

BEGIN
	#声明一个flag变量,默认值为-99
	DECLARE flag INT DEFAULT -99;
	
	#创建companyTempTabl_Qurey临时表
	CREATE TEMPORARY TABLE IF NOT EXISTS companyTempTabl_Qurey (
		id VARCHAR(32) NOT NULL,
		`name` VARCHAR(100),
		attr VARCHAR(30),
		parentId VARCHAR(32)
	);
	TRUNCATE TABLE companyTempTabl_Qurey;
      #创建companyTempTabl_Result临时表
      CREATE TEMPORARY TABLE IF NOT EXISTS companyTempTabl_Result (
		id VARCHAR (32) NOT NULL,
		`name` VARCHAR (100),
		attr VARCHAR (30),
		parentId VARCHAR (32)
	);
	TRUNCATE TABLE companyTempTabl_Result;
	
	#根据参数 parentId 查询数据,并插入companyTempTabl_Qurey临时表
	INSERT INTO companyTempTabl_Qurey (
		id,
		`name`,
		attr,
		parentId
	) SELECT
	uapcompany.id,
	uapcompany.`name`,
	uapcompany.attr,
	uapcompany.parentId
	FROM uapcompany 
	WHERE uapcompany.parentId = `parentId`;
	
      #根据参数 parentId 查询数据,并插入companyTempTabl_Result临时表
	INSERT INTO companyTempTabl_Result (
		id,
		`name`,
		attr,
		parentId
	) SELECT
	uapcompany.id,
	uapcompany.`name`,
	uapcompany.attr,
	uapcompany.parentId
	FROM uapcompany 
	WHERE uapcompany.parentId = `parentId`;
	
	#根据参数 parentId 统计查询总数,并赋值给变量flag
	SELECT count(1) INTO flag 
	FROM uapcompany 
	WHERE uapcompany.parentId = `parentId`;
	
	#如果flag 大于 0,则进行循环
	WHILE flag > 0 DO
		#创建companyTempTabl_temp 临时表
		CREATE TEMPORARY TABLE IF NOT EXISTS companyTempTabl_temp (
			id VARCHAR (32) NOT NULL,
			`name` VARCHAR (100),
			attr VARCHAR (30),
			parentId VARCHAR (32)
		);
		TRUNCATE TABLE companyTempTabl_temp;
		
		#数据库表uapcompany关联临时表companyTempTabl_Qurey查询,并将查询结果插入 临时表companyTempTabl_temp
		INSERT INTO companyTempTabl_temp (id, `name`, attr, parentId) SELECT
			uapcompany.id,
			uapcompany.`name`,
			uapcompany.attr,
			uapcompany.parentId
		FROM
			uapcompany,
			companyTempTabl_Qurey
		WHERE
			uapcompany.parentId = companyTempTabl_Qurey.id;
		
		#删除临时表companyTempTabl_Qurey数据
		DELETE FROM companyTempTabl_Qurey;
		
		#将临时表companyTempTabl_temp的数据 插入companyTempTabl_Qurey临时表,用作下一个循环的条件
		INSERT INTO companyTempTabl_Qurey (id, `name`, attr, parentId) SELECT
			companyTempTabl_temp.id,
			companyTempTabl_temp.`name`,
			companyTempTabl_temp.attr,
			companyTempTabl_temp.parentId
		FROM
			companyTempTabl_temp;
		
		#将临时表companyTempTabl_temp的数据 插入到companyTempTabl_Result临时表(该表的数据也是我们最终要返回的数据)
		INSERT INTO companyTempTabl_Result (id, `name`, attr, parentId) SELECT
			companyTempTabl_temp.id,
			companyTempTabl_temp.`name`,
			companyTempTabl_temp.attr,
			companyTempTabl_temp.parentId
		FROM
			companyTempTabl_temp;
		
		#删除companyTempTabl_temp数据
		DROP TABLE companyTempTabl_temp;
		
		#数据库表uapcompany关联 临时表companyTempTabl_Qurey查询统计,并将结果赋值给变量flag
		SELECT
			count(1) INTO flag
		FROM
			uapcompany,
			companyTempTabl_Qurey
		WHERE
			uapcompany.parentId = companyTempTabl_Qurey.id;
	END WHILE;
	SELECT id ,`name`,attr,parentId  FROM companyTempTabl_Result;

END

 然后保存

测试一下,点击运行

输入参数,点击确定,结果如下图所示

我们在dao层只需要调用一次该 存储过程,就可以返回自己想要的数据,存储过程中创建的临时表随着链接的释放自动删除

原文地址:https://www.cnblogs.com/hjw-zq/p/8820810.html