Java Php Mysql 递归查询 查询当前节点下的所有子节点 包含当前节点返回列表
递归查询
- MySQL
- WITH RECURSIVE语法
- 子查询
- 函数
- JAVA代码
- Hutool 工具
- 执行多次SQL
- 执行一次SQL
- PHP代码
MySQL
1. WITH RECURSIVE语法
使用了MySQL的WITH RECURSIVE语法。首先,它选取了当前节点作为起点,然后在递归的过程中找到了所有它的子节点。最后,它输出了所有找到的节点的标识符。
请注意将查询中的[当前节点的ID]替换为你要查询的节点的ID。
WITH RECURSIVE cte AS (
SELECT id, parent_id
FROM tree_table
WHERE id = [当前节点的ID]
UNION ALL
SELECT t.id, t.parent_id
FROM tree_table t
INNER JOIN cte ON t.parent_id = cte.id
)
SELECT id FROM cte;
2. 子查询
如果你使用的MySQL版本不支持WITH RECURSIVE语法,或者你想尝试不使用WITH RECURSIVE的方法;
这个查询使用了两个子查询。第一个子查询选取了当前节点的ID,并且作为递归查询的起点。第二个子查询从tree_table表中自联结,以查找当前节点的所有子节点。然后,使用JOIN操作将这些子节点与tree_table表中的原始记录匹配,从而得到当前节点下的所有子节点。
请注意将查询中的[当前节点的ID]替换为你要查询的节点的ID。
SELECT t1.id
FROM tree_table t1
JOIN (
SELECT id FROM tree_table WHERE id = [当前节点的ID]
UNION ALL
SELECT t2.id FROM tree_table t2 JOIN tree_table t3 ON t2.parent_id = t3.id
WHERE t3.id = [当前节点的ID]
) t4
ON t1.id = t4.id;
或
SELECT
r1.id,
r1.name,
r1.parent_id
FROM
your_table r1
WHERE
r1.parent_id =[当前节点的ID]
UNION ALL
SELECT
r2.id,
r2.name,
r2.parent_id
FROM
your_table r2
JOIN
your_table r3
ON r2.parent_id = r3.id
WHERE
r3.parent_id = [当前节点的ID]
UNION ALL
SELECT
r4.id,
r4.name,
r4.parent_id
FROM
your_table r4
JOIN
your_table r5
ON r4.parent_id = r5.id
JOIN
your_table r6
ON r5.parent_id = r6.id
WHERE
r6.parent_id = [当前节点的ID]
3. 函数
编写一个存储过程或函数来实现递归查询;将查询中的[当前节点的ID]替换为你要查询的节点的ID。
DELIMITER $$
CREATE FUNCTION get_all_children (node_id INT) RETURNS TEXT
BEGIN
DECLARE child_ids TEXT DEFAULT '';
DECLARE child_id INT;
SELECT GROUP_CONCAT(id) INTO child_ids FROM tree_table WHERE parent_id = node_id;
IF child_ids IS NOT NULL THEN
SET child_ids = CONCAT(child_ids, ',', get_all_children(child_id));
END IF;
RETURN child_ids;
END$$
DELIMITER ;
这个函数使用递归的方式来查询当前节点下的所有子节点。首先,它查找所有直接子节点的ID,并使用GROUP_CONCAT函数将这些ID连接成一个逗号分隔的字符串。然后,对于每个子节点,函数递归调用自己来查找它的子节点,并将它们的ID也连接到返回值中。最后,函数返回一个包含当前节点下所有子节点ID的逗号分隔字符串。
请注意将函数中的tree_table和id和parent_id字段名称替换为你实际使用的表和字段名称。你可以使用以下语句来调用这个函数:
SELECT get_all_children([当前节点的ID]);
将查询中的[当前节点的ID]替换为你要查询的节点的ID。
JAVA代码
Hutool 工具
//创建配置
TreeNodeConfig treeNodeConfig = new TreeNodeConfig();
// 自定义属性名 都要默认值的
treeNodeConfig.setIdKey("id");
treeNodeConfig.setNameKey("name");
treeNodeConfig.setParentIdKey("parent_id");
treeNodeConfig.setChildrenKey("child");
// 最大递归深度 可以不设置
treeNodeConfig.setDeep(3);
/*
* 形参:
* list – 源数据集合
* rootId – 最顶层父id值 一般为 0 之类
* treeNodeConfig – 配置
* nodeParser – 转换器
* 返回值: List
*/
// 构建树结构
List<Tree<String>> build = TreeUtil.build(list, "0", treeNodeConfig, (treeNode, tree) -> {
tree.setId(String.valueOf(treeNode.get("area_id")));
tree.setParentId(String.valueOf(treeNode.get("parent_id")));
tree.setName((CharSequence) treeNode.get("area_name"));
});
执行多次SQL
这个Java方法使用递归的方式来查询当前节点下的所有子节点。首先,它查询所有直接子节点的ID。然后,对于每个子节点,方法递归调用自己来查找它的子节点。最后,方法返回一个包含当前节点下所有子节点ID的列表。
请注意将示例代码中的tree_table和id和parent_id字段名称替换为你实际使用的表和字段名称,以及将数据库连接的URL、用户名和密码替换为你的实际连接信息。
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
public class TreeUtils {
public static List<Integer> getAllChildren(int nodeId, Connection conn) throws SQLException {
List<Integer> childIds = new ArrayList<>();
// 查询所有直接子节点
PreparedStatement stmt = conn.prepareStatement("SELECT id FROM tree_table WHERE parent_id = ?");
stmt.setInt(1, nodeId);
ResultSet rs = stmt.executeQuery();
// 对于每个子节点,递归调用自己来查找它的子节点
while (rs.next()) {
int childId = rs.getInt("id");
childIds.add(childId);
childIds.addAll(getAllChildren(childId, conn));
}
rs.close();
stmt.close();
return childIds;
}
// 使用示例
public static void main(String[] args) {
Connection conn = null;
try {
// 创建数据库连接
conn = DriverManager.getConnection("jdbc:mysql://localhost/mydatabase", "root", "password");
// 查询当前节点的所有子节点
List<Integer> childIds = getAllChildren([当前节点的ID], conn);
// 输出所有子节点的ID
System.out.println(childIds);
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
if (conn != null) {
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
执行一次SQL
这个Java方法首先执行SQL语句查询所有节点,然后将结果集转换为列表。接着使用递归的方式来查询树结构。它遍历列表中的每个节点,如果节点的父ID等于指定的父ID,则将该节点作为当前节点,递归查询该节点的子节点,并将子节点作为嵌套的子树添加到当前节点。最后,方法返回一个包含根节点的树结构的Map对象。
请注意将示例代码中的tree_table和id和parent_id字段名称替换为你实际使用的表和字段名称,以及将数据库连接的URL、用户名和密码
import java.sql.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class TreeUtils {
public static Map<String, Object> buildTree(List<Map<String, Object>> list, int parentId) {
Map<String, Object> node = new HashMap<>();
for (Map<String, Object> item : list) {
int id = (int) item.get("id");
int pid = (int) item.get("parent_id");
if (pid == parentId) {
// 设置当前节点的属性
node.put("id", id);
node.put("name", item.get("name"));
// 递归查询当前节点的子节点
List<Map<String, Object>> children = new ArrayList<>();
for (Map<String, Object> child : list) {
int childPid = (int) child.get("parent_id");
if (childPid == id) {
children.add(buildTree(list, id));
}
}
// 如果有子节点,则将子节点添加到当前节点
if (!children.isEmpty()) {
node.put("children", children);
}
}
}
return node;
}
// 使用示例
public static void main(String[] args) {
Connection conn = null;
try {
// 创建数据库连接
conn = DriverManager.getConnection("jdbc:mysql://localhost/mydatabase", "root", "password");
// 执行SQL语句查询所有节点
PreparedStatement stmt = conn.prepareStatement("SELECT * FROM tree_table");
ResultSet rs = stmt.executeQuery();
// 将结果集转换为列表
List<Map<String, Object>> list = new ArrayList<>();
while (rs.next()) {
Map<String, Object> item = new HashMap<>();
item.put("id", rs.getInt("id"));
item.put("name", rs.getString("name"));
item.put("parent_id", rs.getInt("parent_id"));
list.add(item);
}
// 构建树结构
Map<String, Object> tree = buildTree(list, 0);
// 输出树结构
System.out.println(tree);
rs.close();
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
if (conn != null) {
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
PHP代码
这个PHP函数使用递归的方式来查询当前节点下的所有子节点。首先,它查询所有直接子节点的ID。然后,对于每个子节点,函数递归调用自己来查找它的子节点。最后,函数返回一个包含当前节点下所有子节点ID的数组。
请注意将示例代码中的tree_table和id和parent_id字段名称替换为你实际使用的表和字段名称。如果你使用的是其他语言或框架,可以根据类似的逻辑编写递归函数或方法来实现递归查询。
function get_all_children($node_id, $mysqli) {
$child_ids = array();
// 查询所有直接子节点
$result = $mysqli->query("SELECT id FROM tree_table WHERE parent_id = $node_id");
// 对于每个子节点,递归调用自己来查找它的子节点
while ($row = $result->fetch_assoc()) {
$child_id = $row['id'];
$child_ids[] = $child_id;
$child_ids = array_merge($child_ids, get_all_children($child_id, $mysqli));
}
return $child_ids;
}
// 使用示例
$mysqli = new mysqli('host', 'username', 'password', 'database');
$node_id = 1; // 替换为你要查询的节点的ID
$child_ids = get_all_children($node_id, $mysqli);
print_r($child_ids);
还没有评论,来说两句吧...