首先创建实体类表示与表结构的对应关系
/** * 商品三级分类 * * @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; }