1.分类的实体类
@Table(name = "tb_category")
@Data
public class Category {
@Id
@KeySql(useGeneratedKeys = true)
private Long id;
private String name;
private Long parentId;
private Boolean isParent;
private Integer sort;
}
1.1构建一个分类的扩展类存放一级,二级,三级分类
@Data
@AllArgsConstructor
@NoArgsConstructor
public class CategoryBo {
private Long id;
private Long parentId;
private String name;
private List<CategoryBo> categoryList;
}
1.2编写service获取三级分类的层级结构
1.3实现service方法
@Override
public List<CategoryBo> queryCategoryList() {
List<CategoryBo> categoryBoList = new ArrayList<>();
//构造顶级分类
List<Category> categoryList = new ArrayList<>();
Category category = new Category();
category.setId(0L);
categoryList.add(category);
//获取所有一级分类
List<Category> categoryListOne = getCategoryList(categoryList);
//获取所有二级分类
List<Category> categoryListTwo = getCategoryList(categoryListOne);
//获取所有三级分类
List<Category> categoryListThree = getCategoryList(categoryListTwo);
//合并二级分类和三级分类
List<CategoryBo> CategoryBoMager = magerCategoryList(categoryListTwo, categoryListThree);
if (!CollectionUtils.isEmpty(categoryListOne)) {
for (Category categoryOne : categoryListOne) {
CategoryBo categoryBo = magerCategoryListAll(categoryOne, CategoryBoMager);
categoryBoList.add(categoryBo);
}
}
return categoryBoList;
}
1.4构建一个方法通过上级分类的集合获取下级分类的集合getCategoryList(categoryList)
//根据上级分类获取其下所有子类
private List<Category> getCategoryList(List<Category> categoryList) {
List<Category> list = new ArrayList<>();
if (!CollectionUtils.isEmpty(categoryList)) {
//获取父分类id集合列表,使用Java1.8的新特性获取category的id
List<Long> ids = categoryList.stream().map(Category :: getId).collect(Collectors.toList());
Example example = new Example(Category.class);
example.createCriteria().andIn("parentId", ids);
list = this.categoryMapper.selectByExample(example);
}
return list;
}
我使用的是tkmabatis,上面所代表的查询语句是 select * from tb_category where parent_id in ()
首先先获取到所有的一级,二级,三级的分类
先合并二级分类和三级分类,为什么先合并二三级,而不是一二级呢,那是因为先合并一二级的话,得到一个新的分类扩展类,还要再遍历该扩展类,多了一些操作,而且太麻烦
合并二三级magerCategoryList(categoryListTwo, categoryListThree);
//合并二三级分类
private List<CategoryBo> magerCategoryList(List<Category> categoryListTwo, List<Category> categoryListThree) {
//构建要返回的list集合
List<CategoryBo> categoryBoList = new ArrayList<>();
if (!CollectionUtils.isEmpty(categoryListTwo)) {
for (Category category : categoryListTwo) {
//构建分类扩展类
CategoryBo categoryBo = addCategoryBo(category, categoryListThree);
categoryBoList.add(categoryBo);
}
}
return categoryBoList;
}
//构建二级分类新对象CategoryBo,包含二级分类及其下的三级分类
private CategoryBo addCategoryBo(Category category, List<Category> categoryListThree) {
CategoryBo categoryParent = new CategoryBo();
List<CategoryBo> categoryBoList = new ArrayList<>();
if (!CollectionUtils.isEmpty(categoryListThree)) {
for (Category categoryThree : categoryListThree) {
//二级分类id等于三级分类id
if (categoryThree.getParentId().longValue() == category.getId().longValue()) {
//将三级分类添加到集合中
CategoryBo categoryBo = new CategoryBo();
categoryBo.setId(categoryThree.getId());
categoryBo.setParentId(categoryThree.getParentId());
categoryBo.setName(categoryThree.getName());
categoryBoList.add(categoryBo);
}
}
}
categoryParent.setId(category.getId());
categoryParent.setName(category.getName());
categoryParent.setParentId(category.getParentId());
categoryParent.setCategoryList(categoryBoList);
return categoryParent;
}
合并完二三级分类之后合并一二级分类
//合并一级分类和二级分类
private CategoryBo magerCategoryListAll(Category categoryOne, List<CategoryBo> categoryBoMager) {
List<CategoryBo> categoryBoList = new ArrayList<>();
CategoryBo categoryParent = new CategoryBo();
if (!CollectionUtils.isEmpty(categoryBoMager)) {
for (CategoryBo categoryBo : categoryBoMager) {
//判断一级id是否等于二级的父id,直接加到集合里
if (categoryOne.getId().longValue() == categoryBo.getParentId().longValue()) {
categoryBoList.add(categoryBo);
}
}
}
categoryParent.setId(categoryOne.getId());
categoryParent.setName(categoryOne.getName());
categoryParent.setParentId(0L);
//设置它的子集
categoryParent.setCategoryList(categoryBoList);
return categoryParent;
}
其实可以使用一个方法就可以获取到所有三级分类了,不过我测试了这两种方法,第一种查询数据库比较少,主要是对集合进行操作,第二种的话要查询数据库次数比较多,速度比第一种慢了三倍,第一种花了74ms,第二种214ms,我的数据库分类数据有四百多条
第二种:还是使用分类对象的扩展类,这种方法更多的是使用Java8的新特性
@Override
public List<CategoryBo> queryCategoryBo() {
//获取一级分类
List<Category> categoryList = queryCategoryListByPid(0L);
List<CategoryBo> list = new ArrayList<>();
if(!CollectionUtils.isEmpty(categoryList)){
list = categoryList.stream().map(category ->{
CategoryBo categoryBo = new CategoryBo();
categoryBo.setId(category.getId());
categoryBo.setParentId(category.getParentId());
categoryBo.setName(category.getName());
//获取该分类下的二级分类
List<Category> categoryListTwo = queryCategoryListByPid(category.getId());
//构建二级分类扩展类
List<CategoryBo> categoryBoTwo = categoryListTwo.stream().map(categoryTwo ->{
CategoryBo categoryBo2 = new CategoryBo();
categoryBo2.setId(categoryTwo.getId());
categoryBo2.setParentId(categoryTwo.getParentId());
categoryBo2.setName(categoryTwo.getName());
//获取二级分类下的三级分类
List<Category> categoryListThree = queryCategoryListByPid(categoryTwo.getId());
if(!CollectionUtils.isEmpty(categoryListThree)){
//构建三级分类
List<CategoryBo> categoryBoThree = categoryListThree.stream().map(categoryThree ->{
CategoryBo categoryBo3 = new CategoryBo();
categoryBo3.setId(categoryThree.getId());
categoryBo3.setParentId(categoryThree.getParentId());
categoryBo3.setName(categoryThree.getName());
//三级分类下没有分类了,所以不需要设置categoryBo3.setCategoryList
return categoryBo3;
}).collect(Collectors.toList());
categoryBo2.setCategoryList(categoryBoThree);
}
return categoryBo2;
}).collect(Collectors.toList());
categoryBo.setCategoryList(categoryBoTwo);
return categoryBo;
}).collect(Collectors.toList());
}
return list;
}
根据父分类获取子分类
@Override
public List<Category> queryCategoryListByPid(Long pid) {
//查詢條件,mapper會把對象中的非空屬性作爲查詢條件
Example example = new Example(Category.class);
Example.Criteria criteria = example.createCriteria();
criteria.andEqualTo("parentId",pid);
List<Category> list = categoryMapper.selectByExample(example);
return list;
}
##SQL:select * from tb_category where parent_id = #{pid}