事情场景: 前端使用z-tree插件,需要执行一个删除操作,那么当前节点以及其子节点都要被删除。
方法论:
1.可以在前端做节点向下遍历,生成节点id集合,传给后端,后端mybatis for循环删除即可。
2.可以只穿递当前节点的id,然后用java去数据库中先递归查,构造id集合,然后再删除(回到第一种方法了) 感觉多此一举。
3.直接用sql函数, 前端只传递当前id,sql函数根据当前id来进行表遍历,找到满足条件的id集合,然后update即可。 (项目实际使用方案)
sql函数:
CREATE DEFINER=`xxxxx`@`%` FUNCTION `queryChildrenDocNode`(
`nodeId` INT
)
RETURNS varchar(1000) CHARSET utf8
LANGUAGE SQL
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT ''
BEGIN
DECLARE sTemp VARCHAR(5000);
DECLARE sTempChd VARCHAR(1000);
SET sTemp='$';
SET sTempChd = CAST(nodeId AS CHAR);
WHILE sTempChd IS NOT NULL DO
SET sTemp= CONCAT(sTemp,',',sTempChd);
SELECT GROUP_CONCAT(id) INTO sTempChd FROM 表名 WHERE FIND_IN_SET(pid,sTempChd)>0 and delete_flag = 1;
END WHILE;
RETURN sTemp;
END
### mybatis mapper语句 <update id="deleteDocInfoById" parameterType="java.lang.Long"> UPDATE 表名 SET delete_flag = 1 where find_in_set(id,queryChildrenDocNode(#{id})) </update>
使用此sql函数后,update只能更新两条记录,最后定位问题后发现,是因为上图中的红色字段导致的,删掉红色字段,即可!
猜想:可能是由于sql函数和update都操作同一个字段delete_flag导致的, 估计是sql语句的优先级问题?