先看一波狗东的效果图
可以看出狗东的分类分为三级(实际上多少级都可以)
鄙人的数据库设计
如果父类的id是0的话就是最大的分类
然后直接说设计思路
1.先查出所有分类表的数据(直接service.list)
2.把分类表的数据根据parent_id作为一个Map的分类,大题意思就是spring,springmvc,mybatic的parent_id是0,所以他们是一组的,ioc,bean,aop的parent_id也都是1,所以他们也是同一组,只有aspect的parent_id是4,所以他也单独作为一组,当然resultMap也是单独的一组
3.把每一组里面的内容都遍历,然后如果遍历后的一列(比如spring)的id等于一组的id(相当于parent_id,因为他是根据parent_id作为分组条件的)–
通俗来说spring的child有ioc,bean,aop(aop有child(aspect))
直接上代码(用了mybatisblus)
实体类:
package com.lza.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import java.util.Date;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import java.io.Serializable;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* <p>
* 分类
* </p>
*
* @author lizhaoao
* @since 2021-10-20
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@ApiModel(value="Category对象", description="分类")
//@JsonInclude(JsonInclude.Include.NON_NULL)//json上为空的直接不显示
public class Category implements Serializable {
private static final long serialVersionUID=1L;
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@ApiModelProperty(value = "名称")
private String name;
@ApiModelProperty(value = "父级分类id")
@JsonProperty("parent_id")//数据格式统一
private Integer parentId;
private Date createdAt;
private Date updatedAt;
private Date deletedAt;
//孩子属性,有多个孩子
@TableField(exist = false)//数据库没有这个字段
private List<Category> children;
}
service层
package com.lza.service;
import com.lza.entity.Category;
import com.baomidou.mybatisplus.extension.service.IService;
import com.lza.vo.ChildCategoryVo;
import java.util.List;
/**
* <p>
* 分类 服务类
* </p>
*
* @author lizhaoao
* @since 2021-10-20
*/
public interface CategoryService extends IService<Category> {
public List<ChildCategoryVo> categories();
List<Category> AllCategories();
}
业务层:
@Override
public List<Category> AllCategories() {
//查出所有分类
List<Category> categories = baseMapper.selectList(null);
System.out.println(categories);
//根据parentId分组 null一组,1一组,2一组-----> 0:spring mybatis一组 1:aop ioc bean一组 4:aspect 一组 6:resultMap一组
//设计思路 spring的id==一组id的时候===>spring的child就是该组的内容
Map<Integer,List<Category>> collect=categories.stream().collect(Collectors.groupingBy(Category::getParentId));
List<Category> bei=new ArrayList<>();
System.out.println(JSON.toJSON(collect));
collect.forEach((k,list)->{ //每组中都遍历 ------->(1,spring)(2,mybatis)
list.forEach(b-> {//spring里面有多个键值------> b.id ,b.name,b.parentId
bei.add(b);//把b所有内容赋值给bei先(先遍历所有出来先,因为父分类加载出来的时间字符类有可能还没有加载出来)
});
list=bei;
list.forEach(c->{
if(k.equals(c.getId())){ //如果spring里面的id等于其他分类的parentId,就可以把该分类作为spring的子分类
c.setChildren(collect.get(k));
}
});
});
return collect.get(0);//只返回父这个
}
controller层
private CategoryService categoryService;
//显示所有分类表
@GetMapping("/categories")
public ResponseBean categories(){
List<Category> list = categoryService.AllCategories();
return ResponseBean.success(list);
}
运行结果
大功告成,不过好像有个缺点,时间复杂度应该挺大的