最近在改造公司的代码,之前开发的时候用的是Oracle数据库,现在需要额外写一套支持MySQL的代码,主要是改 MyBatis 里的 XML 代码。
其中一个问题,Oracle 使用 start with connect by prior 来实现递归
Orace递归写法
比如我有一个分类表:t_category
有 id、name、pid 3个字段,其中pid是分类父id的意思。
如果要查询某个分类的所有子节点,包括孙子节点等等
Oracle写法如下:
select * from t_category t
where t.status = '1'
start with t.id = #{id}
connect by prior t.id = t.pid
MyQL想实现递归,需要用存储就过程或者函数
MySQL创建递归函数
针对上面示例,我们创建 MySQL 的分类递归查询函数
CREATE DEFINER=`root`@`%` FUNCTION `get_catgery_child_list`(
in_id VARCHAR ( 50 )) RETURNS varchar(16000) CHARSET utf8mb4 COLLATE utf8mb4_unicode_ci
BEGIN
DECLARE
ids VARCHAR ( 16000 ) DEFAULT '';
DECLARE
tempids VARCHAR ( 16000 );
SET tempids = in_id;
WHILE
tempids IS NOT NULL DO
SET ids = CONCAT_WS( ',', ids, tempids );
SELECT
GROUP_CONCAT( id ) INTO tempids
FROM
t_category
WHERE
FIND_IN_SET( pid, tempids )> 0;
END WHILE;
RETURN ids;
END
MySQL调用函数实现递归
有了上面的函数,我们要实现递归还需要配合 FIND_IN_SET 来使用
SELECT * FROM t_category t
WHERE
and FIND_IN_SET(t.id, get_category_child_list ( #{id} ))
您可以选择一种方式赞助本站
支付宝扫一扫赞助
微信钱包扫描赞助
赏