首先创建实体类表示与表结构的对应关系
/**
* 商品三级分类
*
* @author zhutong
* @email 772929030@qq.com
* @date 2021-08-27 10:40:19
*/
@Data
@TableName("pms_category")
public class CategoryEntity implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 分类id
*/
@TableId
private Long catId;
/**
* 分类名称
*/
private String name;
/**
* 父分类id
*/
private Long parentCid;
/**
* 层级
*/
private Integer catLevel;
/**
* 是否显示[0-不显示,1显示]
*/
private Integer showStatus;
/**
* 排序
*/
private Integer sort;
/**
* 图标地址
*/
private String icon;
/**
* 计量单位
*/
private String productUnit;
/**
* 商品数量
*/
private Integer productCount;
/**
* 目录下的子目录
*/
@TableField(exist = false) //此注解的意思是表中没有这个字段
private List<CategoryEntity> children;
}
然后就是普通的接口层
/**
* 查出所有分类以及子分类,以树状结构组装起来
*/
@RequestMapping("/list/tree")
//@RequiresPermissions("product:category:list")
public R list(){
List<CategoryEntity> categoryEntities = categoryService.listWithTree();
return R.ok().put("data", categoryEntities);
}
重点在于service层,利用lambda和递归实现,一定要注意lambda的行为参数化的写法(详见注释)。lambda还是不够熟悉,性能应该可以通过算法进一步优化
@Service("categoryService")
public class CategoryServiceImpl extends ServiceImpl<CategoryDao, CategoryEntity> implements CategoryService {
@Override
public PageUtils queryPage(Map<String, Object> params) {
IPage<CategoryEntity> page = this.page(
new Query<CategoryEntity>().getPage(params),
new QueryWrapper<CategoryEntity>()
);
return new PageUtils(page);
}
@Override
public List<CategoryEntity> listWithTree() {
List<CategoryEntity> categoryEntities = baseMapper.selectList(null);
List<CategoryEntity> collect = categoryEntities.stream().filter(categoryEntity -> categoryEntity.getParentCid() == 0) //过滤出顶级节点,就是没有父节点的节点
.map(categoryEntity -> {
categoryEntity.setChildren(getChildren(categoryEntity, categoryEntities));
return categoryEntity;
}).sorted(Comparator.comparingInt(item -> (item.getSort() == null ? 0 : item.getSort()))).collect(Collectors.toList());
return collect;
}
/**
* 找出父节点的所有子节点,递归实现,
* 缺点每次都会遍历所有的节点,感觉会影响性能,
* 后期可能需要算法提高性能
* @param fatherCategoryEntity 父节点
* @param all 所有节点
*
* (item1, item2) -> {
* return (item1.getSort() == null ? 0 : item1.getSort()) - (item2.getSort() == null ? 0 : item2.getSort());
* }
*
* Comparator.comparingInt(CategoryEntity::getSort)
* @return
*/
private List<CategoryEntity> getChildren(CategoryEntity fatherCategoryEntity,List<CategoryEntity> all){
List<CategoryEntity> collect = all.stream().filter(categoryEntity -> categoryEntity.getParentCid() == fatherCategoryEntity.getCatId()) //过滤操作,
.map(categoryEntity -> {
categoryEntity.setChildren(getChildren(categoryEntity, all)); //匹配操作,子节点下的字节点
return categoryEntity;
}).sorted(Comparator.comparingInt(item -> (item.getSort() == null ? 0 : item.getSort()))).collect(Collectors.toList()); //排序,lambda的行为参数化
return collect;
}
原文:https://www.cnblogs.com/Theozhu/p/15225734.html