一、实现目标
类似商城三级分类展示,一级、二级、三级目录,逐级包含。
二、数据库设计
image.png
- 分类id为每个类别进行标号,一级分类可能为1-10。
- 父分类id,一级分类默认为0,二级为1-10,三级为二级分类id。
- 层级,记录级别,一级就是1,二三同样。当时在想有父分类id是否不需要层级,但随后想到若用父分类id进行层级划分,不管是代码实现还是后期数据查询都会比较麻烦,不如单独列个字段展示来的直接。
- 是否显示,非常有必要的字段,生产配置表中有个生效开关简直太棒了。
- 排序,直接按照12345排序即可,后台相减比较。商城目录排序是非常有必要的。
- 其他都是些公共字段,不做展开介绍。
三、代码实现
3.1 查出该表所有数据及筛选一级菜单
public List<CategoryEntity> listWithTreeNew(){
//获取菜单表所有信息
List<CategoryEntity> categoryEntities = baseMapper.selectList(null);
//获取所有一级菜单
List<CategoryEntity> levelOneMenus = categoryEntities.stream().filter((categoryEntity) -> {
return categoryEntity.getParentCid() == 0;
}).collect(Collectors.toList());
return null;
}
- baseMapper为mybatisplus的父类方法的变量,通过泛型继承,父类已经注入,直接使用即可。
- java\util\stream\Stream接口详细介绍:https://blog.csdn.net/y_k_y/article/details/84633001
本人粗略测试filter方法后总结:
a. Collection集合接口有Stream方法,Map无。list和set都可以使用。将其转化为流。
b. filter内的方法,参数为list遍历的对象。比如图中参数为每次遍历的CategoryEntity类的对象,括号内只是参数名称,类似于方法传参的别名。
categoryEntities.stream().filter((CategoryEntity 别名) -> {
//各种筛选条件,或者适当逻辑亦可
return true;
}).collect(Collectors.toList());
c. lmade表达式中,方法返回值为布尔类型。
d. 若返回true则说明该数据符合进行保留,false则舍弃。
e. 若参数一个,圆括号可以省略,方法体只有一行,大括号可以省略。
f. 当时在想为何拿父分类为0来筛选一级,而不是直接拿层级。后来想一级夫分类修改几率不大,而层级几率大些。
public List<CategoryEntity> listWithTreeNew(){
//获取菜单表所有信息
List<CategoryEntity> categoryEntities = baseMapper.selectList(null);
//获取所有一级菜单
List<CategoryEntity> levelOneMenus = categoryEntities.stream().filter(categoryEntity ->
categoryEntity.getParentCid() ==0
).collect(Collectors.toList());
return null;
}
3.2 一级目录加装二级菜单
public List<CategoryEntity> listWithTree() {
//获取菜单表所有信息
List<CategoryEntity> categoryEntities = baseMapper.selectList(null);
//获取所有一级菜单
List<CategoryEntity> levelOneMenus = categoryEntities.stream().filter(categoryEntity ->
categoryEntity.getParentCid() ==0
).collect(Collectors.toList());
//map用于映射每个元素到对应的结果
List<CategoryEntity> collect = levelOneMenus.stream().map((oneMenus) -> {
//得到一级菜单下所有子菜单
List<CategoryEntity> collect1 = categoryEntities.stream().filter((categoryEntity) -> {
return categoryEntity.getParentCid() == oneMenus.getCatId();
}).collect(Collectors.toList());
oneMenus.setChildren(collect1);
return oneMenus;
}).collect(Collectors.toList());
return null;
a. map用于映射每个元素到对应的结果。说白了每个遍历做一下功能增强。
b. 上述代码中,可以再次进行嵌套将三级菜单放入二级菜单的setChildren中。但显得代码不简洁。
3.3 递归调用
public List<CategoryEntity> listWithTree() {
//获取菜单表所有信息
List<CategoryEntity> categoryEntities = baseMapper.selectList(null);
//获取所有一级菜单
List<CategoryEntity> levelOneMenus = categoryEntities.stream().filter(categoryEntity ->
categoryEntity.getParentCid() ==0
).map(oneMenus -> {
oneMenus.setChildren(getChildrens(oneMenus,categoryEntities));
return oneMenus;
}).collect(Collectors.toList());
return null;
}
//递归查找所有菜单的子菜单
private List<CategoryEntity> getChildrens(CategoryEntity root,List<CategoryEntity> all){
List<CategoryEntity> children = all.stream().filter(categoryEntity -> {
return categoryEntity.getParentCid() == root.getCatId();
}).map(categoryEntity -> {
//1、找到子菜单
categoryEntity.setChildren(getChildrens(categoryEntity,all));
return categoryEntity;
}).collect(Collectors.toList());
return children;
}
a. 此代码则无需考虑菜单级别问题,就算有十级菜单亦可轻松应对。
b. 另外对主方法多个stream进行了合并,效果相同。
3.4 增加排序
public List<CategoryEntity> listWithTree() {
//获取菜单表所有信息
List<CategoryEntity> categoryEntities = baseMapper.selectList(null);
//获取所有一级菜单
List<CategoryEntity> levelOneMenus = categoryEntities.stream().filter(categoryEntity ->
categoryEntity.getParentCid() ==0
).map(oneMenus -> {
oneMenus.setChildren(getChildrens(oneMenus,categoryEntities));
return oneMenus;
}).sorted((menu1,menu2)->{
//2、菜单的排序
return (menu1.getSort()==null?0:menu1.getSort()) - (menu2.getSort()==null?0:menu2.getSort());
}).collect(Collectors.toList());
return null;
}
//递归查找所有菜单的子菜单
private List<CategoryEntity> getChildrens(CategoryEntity root,List<CategoryEntity> all){
List<CategoryEntity> children = all.stream().filter(categoryEntity -> {
return categoryEntity.getParentCid() == root.getCatId();
}).map(categoryEntity -> {
//1、找到子菜单
categoryEntity.setChildren(getChildrens(categoryEntity,all));
return categoryEntity;
}).sorted((menu1,menu2)->{
//2、菜单的排序
return (menu1.getSort()==null?0:menu1.getSort()) - (menu2.getSort()==null?0:menu2.getSort());
}).collect(Collectors.toList());
return children;
}
a. sorted提供排序方法,返回值为int。细节不清,后续研究。















网友评论