在实际业务中,分类表中或菜单表中 数据得关系会有一种树形关系,在表的设计中一般会在表中添加一个parentId
字段,
在查询这类数据一般有两种方式
一种是采用业务逻辑将其组装成树状结构
另外一种是通过sql
语句及mybatis
将其组装成树状结构
使用流将分类关系组成树状结构
/**
* 以树形结构返回
*
* @return
*/
@Override
public List<UmsMenuNode> treeList() {
//所有的菜单
List<UmsMenu> menuList = umsMenuMapper.selectByExample(new UmsMenuExample());
//将菜单组装成节点
List<UmsMenuNode> nodes = menuList.stream()
//找出所有父节点
.filter(menu -> menu.getParentId().equals(0L))
.map(menu -> covertMenuNode(menu, menuList))
.collect(Collectors.toList());
return nodes;
}
/**
* 将UmsMenu 转化为UmsMenuNode 并设置children属性 递归完成
*
* @param menu
* @param menuList
* @return
*/
private UmsMenuNode covertMenuNode(UmsMenu menu, List<UmsMenu> menuList) {
UmsMenuNode node = new UmsMenuNode();
BeanUtil.copyProperties(menu, node);
List<UmsMenuNode> children = menuList.stream()
.filter(subMenu -> subMenu.getParentId().equals(menu.getId()))
.map(subMenu -> covertMenuNode(subMenu, menuList))
.collect(Collectors.toList());
node.setChildren(children);
return node;
}
sql完成树状分类 只有两级
商品分类实体类
public class PmsProductCategory implements Serializable {
private Long id;
@ApiModelProperty(value = "上机分类的编号:0表示一级分类")
private Long parentId;
private String name;
@ApiModelProperty(value = "分类级别:0->1级;1->2级")
private Integer level;
private Integer productCount;
private String productUnit;
@ApiModelProperty(value = "是否显示在导航栏:0->不显示;1->显示")
private Integer navStatus;
@ApiModelProperty(value = "显示状态:0->不显示;1->显示")
private Integer showStatus;
private Integer sort;
@ApiModelProperty(value = "图标")
private String icon;
private String keywords;
@ApiModelProperty(value = "描述")
private String description;
商品分类返回实体类
/**
* @author by cyf
* @date 2020/6/15.
*/
@Getter
@Setter
public class PmsProductCategoryWithChildren extends PmsProductCategory {
private List<PmsProductCategory> children;
}
sql
语句
<resultMap id="listWithChildren" type="com.cyf.malldemo.dto.PmsProductCategoryWithChildren"
extends="com.cyf.malldemo.mbg.mapper.PmsProductCategoryMapper.BaseResultMap">
<collection property="children" resultMap="com.cyf.malldemo.mbg.mapper.PmsProductCategoryMapper.BaseResultMap"
columnPrefix="child_"></collection>
</resultMap>
<select id="listWithChildren" resultMap="listWithChildren">
select
c1.id,
c1.name,
c2.id child_id,
c2.name child_name
from pms_product_category c1
left join pms_product_category c2
on c1.id = c2.parent_id
where c1.parent_id = 0
</select>
</mapper>
在mysql
中查询得到数据, ``mybatis根据
resultMap`封装进对象
mysql> use mall;
Database changed
mysql> select
c1.id,
c1.name,
c2.id child_id,
c2.name child_name
from pms_product_category c1
left join pms_product_category c2
on c1.id = c2.parent_id
where c1.parent_id = 0;
+----+----------+----------+--------------+
| id | name | child_id | child_name |
+----+----------+----------+--------------+
| 1 | 服装 | 7 | 外套 |
| 1 | 服装 | 8 | T恤 |
| 1 | 服装 | 9 | 休闲裤 |
| 1 | 服装 | 10 | 牛仔裤 |
| 1 | 服装 | 11 | 衬衫 |
| 2 | 手机数码 | 19 | 手机通讯 |
| 1 | 服装 | 29 | 男鞋 |
| 2 | 手机数码 | 30 | 手机配件 |
| 2 | 手机数码 | 31 | 摄影摄像 |
| 2 | 手机数码 | 32 | 影音娱乐 |
| 2 | 手机数码 | 33 | 数码配件 |
| 2 | 手机数码 | 34 | 智能设备 |
| 3 | 家用电器 | 35 | 电视 |
| 3 | 家用电器 | 36 | 空调 |
| 3 | 家用电器 | 37 | 洗衣机 |
| 3 | 家用电器 | 38 | 冰箱 |
| 3 | 家用电器 | 39 | 厨卫大电 |
| 3 | 家用电器 | 40 | 厨房小电 |
| 3 | 家用电器 | 41 | 生活电器 |
| 3 | 家用电器 | 42 | 个护健康 |
| 4 | 家具家装 | 43 | 厨房卫浴 |
| 4 | 家具家装 | 44 | 灯饰照明 |
| 4 | 家具家装 | 45 | 五金工具 |
| 4 | 家具家装 | 46 | 卧室家具 |
| 4 | 家具家装 | 47 | 客厅家具 |
| 5 | 汽车用品 | 48 | 全新整车 |
| 5 | 汽车用品 | 49 | 车载电器 |
| 5 | 汽车用品 | 50 | 维修保养 |
| 5 | 汽车用品 | 51 | 汽车装饰 |
| 1 | 服装 | 54 | 改手表大哥大 |
+----+----------+----------+--------------+
30 rows in set