话不多说,直接上代码
方式一:for循环嵌套一下
@Override
public List<GoodsType> findNodes() {
Long parentId = 0L;
List<GoodsType> levelOneGoodsTypeList = getList(parentId);
for (GoodsType levelOne : levelOneGoodsTypeList) {
List<GoodsType> levelTwoGoodsTypeList = getList(levelOne.getId());
levelOne.setChildren(levelTwoGoodsTypeList);
for (GoodsType levelTwo : levelTwoGoodsTypeList) {
List<GoodsType> levelThreeGoodsTypeList = getList(levelTwo.getId());
levelTwo.setChildren(levelThreeGoodsTypeList);
}
}
return levelOneGoodsTypeList;
}
方式二:Mybatis N级递归查询
String json = redisTemplate.opsForValue().get(RedisConst.GOODS_TYPE_NODES_CACHE);
List<GoodsType> goodsTypes = JSONObject.parseArray(json, GoodsType.class);
if (goodsTypes == null) {
goodsTypes = goodsTypeMapper.findNodes(0L);
hasChildList(goodsTypes);
redisTemplate.opsForValue().set(RedisConst.GOODS_TYPE_NODES_CACHE, JSONObject.toJSONString(goodsTypes), 10, TimeUnit.DAYS);
}
<resultMap id="nestedMap" type="com.atguigu.wms.model.base.GoodsType" autoMapping="true">
<id property="id" column="id"></id>
<result property="label" column="name"></result>
<result property="value" column="id"></result>
<collection property="children"
column="id"
select="findNodes"
ofType="com.atguigu.wms.model.base.GoodsType"></collection>
</resultMap>
<select id="findNodes" resultMap="nestedMap">
SELECT
id,
name,
parent_id,
create_time,
update_time
FROM
goods_type
WHERE
parent_id = #{parentId}
</select>
方式三:Stream流递归处理
public List<GoodsType> findTree(){
List<GoodsType> all = baseMapper.selectList(null);
return all.stream().filter(item ->
item.getParentId() == 0
).peek(child -> {
child.setChildren(findNodesTree(child, all));
child.setLabel(child.getName());
child.setValue(child.getId().toString());
}).collect(Collectors.toList());
}
private List<GoodsType> findNodesTree(GoodsType goodsType, List<GoodsType> all) {
return all
.stream()
.filter((child -> Objects.equals(goodsType.getId(), child.getParentId())))
.peek((child -> {
child.setChildren(findNodesTree(child, all));
child.setLabel(child.getName());
child.setValue(child.getId().toString());
}))
.peek(child -> {
if (child.getChildren() == null || child.getChildren().size() == 0) child.setChildren(null);
})
.collect(Collectors.toList());
}
效果如下

【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具