用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層只需要調用一次該 存儲過程,就可以返回自己想要的數據,存儲過程中創建的臨時表隨着鏈接的釋放自動刪除

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM