SQL中查询树结构式结果

//SQL中查询树结构式结果

SQL:Select   A.ID,A.GNWZMC,A.idx,B.idx   As   ParentIdx,A.级数  
From   (Select   Rownum   As   Idx,Level   As   级数,ID,FID,GNWZMC
From   GY_SB_WJJG 
Start   With   FID='-1'   Connect   By   Prior   ID=FID)   A,  
(Select   Rownum   As   Idx,ID    
From   GY_SB_WJJG   
Start   With    FID='-1'    Connect   By   Prior   ID=FID)   B  
Where   A.FID=B.ID  
Order   By   A.idx 

//当然可以用start with 

### 使用 MyBatis 构建形结构的 SQL 查询实现 在构建形结构时,通常会涉及自关联表的设计模。这种设计允许通过父节点和子节点的关系来表示层次化的数据结构。以下是基于 MyBatis 的一种常见方法来查询并构建形结构。 #### 数据库表设计 假设有一个 `tree` 表,其字段如下: | Column Name | Description | |-------------|---------------------| | id | 唯一标识符 | | parent_id | 父级节点 ID | | name | 节点名称 | 其中,`parent_id` 字段用于指向当前记录的父节点。如果该节点是一个根节点,则可以将其设置为 NULL 或者自身的 `id`。 --- #### SQL 查询语句 为了获取整个形结构的数据,可以通过递归查询或者一次性加载所有节点的方完成。以下是一次性加载所有节点的 SQL 示例[^1]: ```sql SELECT id, parent_id, name FROM tree; ``` 此查询返回所有的节点信息,之后可以在应用程序层面上对其进行处理以形成形结构。 对于支持递归查询的数据库(如 PostgreSQL),也可以使用 Common Table Expressions (CTE) 来执行递归查询。例如: ```sql WITH RECURSIVE TreeHierarchy AS ( SELECT id, parent_id, name FROM tree WHERE parent_id IS NULL -- 获取根节点 UNION ALL SELECT t.id, t.parent_id, t.name FROM tree t INNER JOIN TreeHierarchy th ON t.parent_id = th.id ) SELECT * FROM TreeHierarchy; ``` 上述 CTE 查询能够自动遍历整棵,并按层级顺序返回结果。 --- #### MyBatis 映射配置 MyBatis 中可以通过 `<select>` 标签定义查询逻辑,并结合 Java 对象映射到形结构中。下面展示如何编写对应的 Mapper 文件以及实体类。 ##### 1. Entity 类 创建一个简单的 Java 实体类代表中的每一个节点: ```java public class TreeNode { private Integer id; private Integer parentId; private String name; private List<TreeNode> children; // Getters and Setters omitted for brevity. } ``` 注意这里的 `children` 属性用来存储当前节点的所有子节点。 ##### 2. Mapper 接口与 XML 配置 Mapper 接口中声明的方法应匹配前面提到的 SQL 查询: ```java import java.util.List; public interface TreeMapper { List<TreeNode> getAllNodes(); } ``` XML 配置文件则负责提供具体的 SQL 定义: ```xml <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.example.mapper.TreeMapper"> <select id="getAllNodes" resultType="TreeNode"> SELECT id, parent_id as parentId, name FROM tree; </select> </mapper> ``` 此处需要注意的是,由于列名可能与属性名不一致,因此需要显指定别名(如 `parent_id as parentId`)以便正确映射至对象。 --- #### 后续处理:构建形结构 从数据库读取的结果集通常是扁平化列表形,需进一步转换成嵌套状结构。这一步骤一般由业务逻辑代码完成。以下是一个示例算法: ```java import java.util.*; import java.util.stream.Collectors; public class TreeBuilder { public static TreeNode buildTree(List<TreeNode> nodes) { Map<Integer, TreeNode> nodeMap = new HashMap<>(); // 将所有节点存入 map 方便查找 for (TreeNode node : nodes) { node.setChildren(new ArrayList<>()); nodeMap.put(node.getId(), node); } TreeNode root = null; // 记录最终的根节点 for (TreeNode node : nodes) { if (node.getParentId() == null || !nodeMap.containsKey(node.getParentId())) { root = node; // 如果找不到父节点,则认为它是根节点 } else { TreeNode parentNode = nodeMap.get(node.getParentId()); parentNode.getChildren().add(node); // 添加到对应父节点的孩子集合里 } } return root; } } ``` 调用以上函数即可获得完整的形结构实例。 --- #### 注意事项 当涉及到动态参数传递时,请务必遵循安全编码实践以防注入攻击。例如,在 XPath 注入防护方面建议始终采用预编译方构造表达[^2]。 此外,若运行环境依赖容器化部署方案,可参考 Docker Redis 运行命令确保缓存服务正常启动[^3]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值