document
API test

树形查询

GET
http://localhost:88/api/product/category/list/tree

API description

树形查询所有的分类

Response Parameters

parameter
type
description
required
msg
string
(示例) success
required
code
string
(示例) 0
required
data
object
示例数据
required
catId
long
required
name
string
required
parentCid
long
required
catLevel
integer
required
showStatus
integer
required
sort
integer
required
icon
string
required
productUnit
string
required
productCount
integer
required
children
array
required

Description or Example

# 核心代码 ```java @RequestMapping("/list/tree") public R listTree() { List<CategoryEntity> categoryEntities = categoryService.queryCategoryEntitiesWithTree(); return R.ok().put("data", categoryEntities); } ``` ```java /** * 树形查询出所有的分类记录 * @return 树形的分类记录集合 */ @Override public List<CategoryVO> queryCategoryEntitiesWithTree() { List<CategoryEntity> categoryEntities = baseMapper.selectList(null); return categoryEntities .stream() // 获取stream流 .filter(categoryEntity -> categoryEntity.getParentCid() == 0L) // 由于一级分类没有父分类, 因此父分类的id为0, 这里是找出所有的一级分类 .map(categoryEntity -> { // 映射主要是调用下述方法, 找出该分类的子分类 CategoryVO categoryVO = new CategoryVO(); BeanUtils.copyProperties(categoryEntity, categoryVO); categoryVO.setChildren(queryCategoryEntityChildren(categoryEntities, categoryEntity)); return categoryVO; }) .sorted((c1, c2) -> (c1.getSort() == null ? 0 : c1.getSort()) - (c2.getSort() == null ? 0 : c2.getSort())) // 根据sort字段排序 .collect(Collectors.toList()); } /** * 查询某一个分裂的子分类 * @param categoryEntities 所有的分类记录, 从这里找 * @param categoryEntity 父分类 * @return 子分类集合 */ private List<CategoryVO> queryCategoryEntityChildren(List<CategoryEntity> categoryEntities, CategoryEntity categoryEntity) { return categoryEntities .stream() .filter(category -> Objects.equals(category.getParentCid(), categoryEntity.getCatId())) // 如果子分类的父分类ID等于参数分类ID, 说明对应 .map(category -> { CategoryVO categoryVO = new CategoryVO(); BeanUtils.copyProperties(category, categoryVO); categoryVO.setChildren(queryCategoryEntityChildren(categoryEntities, category)); return categoryVO; // 同理, 子分类仍然可能存在子分类, 因此可以通过继续调用该方法递归查找 }) .sorted((c1, c2) -> (c1.getSort() == null ? 0 : c1.getSort()) - (c2.getSort() == null ? 0 : c2.getSort())) // 根据sort字段排序 .collect(Collectors.toList()); // 同理 } ``` ## 亮点: > **1. 这个树形查询的方法整体的思路是将全部数据一次性查询出来, 然后通过stream流做过滤和映射** > > **2. 查找子分类的方法使用了递归查找** ### 好处: 1. 这样做的好处是, 避免了重复查询数据库, 只需要建立一次与数据库的连接, 就可以在应用层完成树形集合 因为避免了查询数据库, 不需要频繁建立销毁连接. 提高效率 ### 细节: 1. **在进行排序的时候一定要对NULL进行三目运算操作, 因为sort字段是Integer类型的, `null-null`会造成空指针异常, 因此需要对NULL判断**