mybatis 一条数据构建树形结构
时间: 2025-03-24 17:19:31 浏览: 30
### 使用 MyBatis 构建单条数据的树形结构
构建单条数据的树形结构可以通过多种方式实现,以下是基于 MyBatis 的两种主要方法:
#### 方法一:嵌套结果集映射
通过 `resultMap` 和 `<association>` 或 `<collection>` 标签来定义父子关系。这种方式适用于已知父节点和子节点的关系,并能够一次性加载整个树形结构。
假设有一个权限表 `permission`,其中包含字段 `id`, `name`, `parent_id`。为了查询某个特定 ID 的记录及其所有的子节点,可以在 Mapper 文件中这样配置[^1]:
```xml
<resultMap type="com.example.Permission" id="treeResultMap">
<id property="id" column="id"/>
<result property="name" column="name"/>
<!-- 定义子节点集合 -->
<collection property="children" ofType="com.example.Permission" resultMap="treeResultMap"/>
</resultMap>
<select id="selectTreeById" parameterType="int" resultMap="treeResultMap">
SELECT * FROM permission WHERE parent_id = #{parentId} OR id = #{parentId}
</select>
```
上述代码片段中的 `resultMap` 配置了一个递归的结果映射,允许将每一级的数据都作为上一级的子节点处理。当调用 `selectTreeById` 时传入根节点的 `id` 值即可获取完整的树形结构。
#### 方法二:Service 层递归组装
另一种常见的做法是在 Service 层完成递归逻辑。数据库仅负责返回扁平化的列表数据,之后由程序动态计算出层次关系。
首先,在 DAO 层编写 SQL 获取所有相关联的数据项:
```sql
SELECT * FROM permission;
```
接着在 Java 中创建一个辅助函数用于查找指定节点下的所有后代节点[^2]:
```java
public Permission buildTree(List<Permission> allPermissions, int rootId) {
Optional<Permission> rootOptional = allPermissions.stream()
.filter(p -> p.getId().equals(rootId))
.findFirst();
if (rootOptional.isPresent()) {
Permission rootNode = rootOptional.get();
rootNode.setChildren(getChildNodes(allPermissions, rootNode));
return rootNode;
}
return null;
}
private List<Permission> getChildNodes(List<Permission> allPermissions, Permission parentNode) {
return allPermissions.stream()
.filter(permission -> Objects.equals(parentNode.getId(), permission.getParentId()))
.peek(child -> child.setChildren(getChildNodes(allPermissions, child)))
.collect(Collectors.toList());
}
```
这种方法的优点在于灵活性较高,尤其适合那些无法直接利用 ORM 工具生成复杂嵌套对象的情况;缺点则是可能增加内存消耗以及降低性能效率,因为需要额外遍历整个数据集多次才能得到最终结果。
无论采用哪种方案都需要确保模型类支持存储多层嵌套属性(即内部应含有指向相同类型的成员变量),例如:
```java
public class Permission implements Serializable {
private Integer id;
private String name;
private Integer parentId;
@JsonIgnore // 如果使用 Jackson 序列化工具,则需防止循环引用错误
private List<Permission> children;
// Getter & Setter methods...
}
```
以上就是关于如何借助 MyBatis 来实现单条数据对应的树形结构的主要思路介绍。
阅读全文
相关推荐

















