我正在参加「掘金·启航计划」
返回树形结构数据
通过Java语言操作
如果我们想要返回树形结构的数据形式,类似于评论这种,那通过Java操作其实就是:
- 首先查到所要的完整数据
- 由于树形数据一定是有父节点的编号的,所以肯定写成递归
- 可以通过stream来优美的表示
上代码(这里使用了mybatis-plus):
//递归查找所有菜单的子菜单
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;
}
public List<CategoryEntity> listWithTree() {
//1、查出所有分类
List<CategoryEntity> entities = baseMapper.selectList(null);
//2、组装成父子的树形结构
// 找到所有的一级分类
List<CategoryEntity> level1Menus = entities.stream().filter(categoryEntity ->
categoryEntity.getParentCid() == 0
).map((menu) -> {
menu.setChildren(getChildrens(menu, entities));
return menu;
}).sorted((menu1, menu2) -> {
return (menu1.getSort() == null ? 0 : menu1.getSort()) - (menu2.getSort() == null ? 0 : menu2.getSort());
}).collect(Collectors.toList());
return level1Menus;
}
listWithTree就是我们的方法,递归调用了getChildrens来查找,而setChildren就是一个setter方法
通过Mybatis操作
先创建一个数据表
create table tree
(
id bigint not null
primary key,
parent_id bigint not null,
sort int not null,
name varchar(100) not null
);
一些数据
INSERT INTO MY_TABLE(id, first_name, last_name, birth) VALUES (10001, 'Georgi', 'Facello', 'M');
INSERT INTO MY_TABLE(id, first_name, last_name, birth) VALUES (10002, 'Bezalel', 'Simmel', 'F');
INSERT INTO MY_TABLE(id, first_name, last_name, birth) VALUES (10003, 'Parto', 'Bamford', 'M');
INSERT INTO MY_TABLE(id, first_name, last_name, birth) VALUES (10004, 'Chirstian', 'Koblick', 'M');
INSERT INTO MY_TABLE(id, first_name, last_name, birth) VALUES (10005, 'Kyoichi', 'Maliniak', 'M');
INSERT INTO MY_TABLE(id, first_name, last_name, birth) VALUES (10006, 'Anneke', 'Preusig', 'F');
INSERT INTO MY_TABLE(id, first_name, last_name, birth) VALUES (10007, 'Tzvetan', 'Zielinski', 'F');
INSERT INTO MY_TABLE(id, first_name, last_name, birth) VALUES (10008, 'Saniya', 'Kalloufi', 'M');
INSERT INTO MY_TABLE(id, first_name, last_name, birth) VALUES (10009, 'Sumant', 'Peac', 'F');
INSERT INTO MY_TABLE(id, first_name, last_name, birth) VALUES (10010, 'Duangkaew', 'Piveteau', 'F');
对应的bean
@Getter
@Setter
@ToString
public class Tree {
private Long id;
private Long parentId;
private Integer sort;
private String name;
private List<Tree> children;
}
这里面关键词都很好懂,sort就是排序字段,children就是子数据
来个Mapper
@Mapper
public interface TreeMapper {
List<Tree> getAllSort();
}
对应的xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.he.dao.TreeMapper">
<resultMap id="resultMap" type="com.he.pojo.Tree">
<id column="id" property="id"/>
<result column="parent_id" property="parentId"/>
<result column="sort" property="sort"/>
<result column="name" property="name"/>
<!--使用mybatis collection 进行集合查询-->
<collection property="children" ofType="com.he.pojo.Tree" select="selectTree" column="id"
javaType="java.util.ArrayList"/>
</resultMap>
<!--父级查询-->
<select id="getAllSort" resultMap="resultMap">
<!--从parent_id为0开始递归-->
select * from tree where parent_id = 0 order by sort asc
</select>
<!--关联集合查询-->
<select id="selectTree" parameterType="String" resultMap="resultMap">
select *
from tree
where tree.parent_id = #{id}
order by sort asc
</select>
</mapper>
使用collection进行操作,里面嵌套了select的sql就可以了
这里面还有通过两个字段来定位1对多的情况,其实就是在collection的column中换成column="{id=id,grade=grade}"这样就可以一次性传2个参数。