话不多说,直接上代码
方式一:for循环嵌套一下
/**
* 查询三级分类
*
* @return
*/
@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);
// TODO 设置其他前端需要的值
}
}
return levelOneGoodsTypeList;
}
方式二:Mybatis N级递归查询
// 方式二:使用自定义SQL语句,查询三级分类
// 查询redis中是否存在
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);
// 存入redis中
hasChildList(goodsTypes);
redisTemplate.opsForValue().set(RedisConst.GOODS_TYPE_NODES_CACHE, JSONObject.toJSONString(goodsTypes), 10, TimeUnit.DAYS);
}
// 下面的代码是mapper.xml中的
<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(){
//1.查出所有分类
List<GoodsType> all = baseMapper.selectList(null);
// return findNodesTree(all.get(0),all);
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());
}
/**
* 递归查询子节点
*
* @param goodsType
* @param all
* @return
*/
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());
}
效果如下
