1,三级分类树形结构查询
/*** DDD(Domain-Driven Design): 领域驱动设计** 三级分类树形结构;* 支持无限层级;* 当前项目只有三级*/
@Data
public class CategoryTreeTo {private Long categoryId; //1private String categoryName;private List<CategoryTreeTo> categoryChild;//子分类
}
<!-- 定义Category树形封装规则; 三级固定封装--><resultMap id="CategoryTreeRM" type="com.azxc.rapid.modules.main.dto.CategoryTreeTo"><!-- 一级分类的规则 --><id column="id" property="categoryId"></id><result column="name" property="categoryName"></result><collection property="categoryChild"ofType="com.azxc.rapid.modules.main.dto.CategoryTreeTo"><!-- 二级分类封装规则 --><id column="c2_id" property="categoryId"></id><result column="c2_name" property="categoryName"></result><collection property="categoryChild"ofType="com.azxc.rapid.modules.main.dto.CategoryTreeTo"><!-- 三级分类封装规则 --><id column="c3_id" property="categoryId"></id><result column="c3_name" property="categoryName"></result></collection></collection></resultMap><select id="getTest" resultMap="CategoryTreeRM">select bc1.*,bc2.id c2_id,bc2.name c2_name,bc2.category1_id,bc3.id c3_id,bc3.name c3_name,bc3.category2_idfrom base_category1 bc1left join base_category2 bc2 on bc1.id = bc2.category1_idleft join base_category3 bc3 on bc2.id = bc3.category2_id</select>
执行结果展示
2,树形结构(递归遍历)
@Overridepublic List<Permission> getTest1() {//查询所有菜单List<Permission> res = baseMapper.getTest1();return build(res);}/*** 根据权限列表构建父子关系** @param permissionList* @return*/public static List<Permission> build(List<Permission> permissionList) {List<Permission> menu = new ArrayList<>();for (Permission permission : permissionList) {//判断当前菜单是否是以及菜单if (permission.getParentId() == 0) {//一级菜单//2.1 设置一级菜单的子菜单列表permission.setChildren(getChildren(permission, permissionList));//2.2 将一级菜单添加到菜单列表中menu.add(permission);}}return menu;}/*** 从原始菜单中获取某个权限的子菜单列表** @param permission* @param originPermissionList* @return*/private static List<Permission> getChildren(Permission permission, List<Permission> originPermissionList) {//1. 创建一个新的集合,用来存储子菜单List<Permission> children = new ArrayList<>();//1. 遍历出原始菜单中的每一个权限for (Permission child : originPermissionList) {//1.1 如果originPermission的父id等于permission的idif (permission.getId().equals(child.getParentId())) {//originPermission是permission的子菜单,则将originPermission添加到children中// 子菜单还有没有子菜单呢?child.setChildren(getChildren(child, originPermissionList));children.add(child);}}return children;}
结果 :
表结构:树形结构
3,数据字典
需求效果图
表结构:树形结构
1.xml
<select id="findListByParentId" resultType="com.atguigu.entity.Dict"><include refid="columns"></include>from hse_dictwhere parent_id = #{parentId} and is_deleted = 0</select>
2.业务层
@Overridepublic List<Map<String, Object>> findZnodes(Long id) {//根据id查询对应的子分类List<Dict> dictList = dictMapper.findListByParentId(id);//使用Stream API将dictList转换为Map集合List<Map<String, Object>> zNodes = dictList.stream().map(dict -> {Map<String, Object> responseMap = new HashMap<>();//表示当前节点是否还有子节点,以当前节点的id到hse_dict表中查询子节点的数量,如果大于0,则表示当前节点还有子节点Integer count = dictMapper.countIsParent(dict.getId());responseMap.put("isParent", count > 0);//表示当前节点的名称responseMap.put("name", dict.getName());responseMap.put("id", dict.getId());return responseMap;}).collect(Collectors.toList());return zNodes;}
4,stream流递归实现
实体类
public class TreeBean {/*** id*/private Integer id;/*** 名称*/private String name;/*** 父id ,根节点为0*/public Integer parentId;/*** 子节点信息*/public List<TreeBean> childList;public TreeBean() {}public TreeBean(Integer id, String name, Integer parentId, List<TreeBean> childList) {this.id = id;this.name = name;this.parentId = parentId;this.childList = childList;}public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Integer getParentId() {return parentId;}public void setParentId(Integer parentId) {this.parentId = parentId;}public List<TreeBean> getChildList() {return childList;}public void setChildList(List<TreeBean> childList) {this.childList = childList;}/*** 初始化数据* @return*/public List<TreeBean> initializationData() {List<TreeBean> list = new ArrayList<>();TreeBean t1 = new TreeBean(1, "广东省", 0, new ArrayList<>());TreeBean t2 = new TreeBean(2, "湖南省", 0, new ArrayList<>());TreeBean t3 = new TreeBean(3, "广州市", 1, new ArrayList<>());TreeBean t4 = new TreeBean(4, "长沙市", 2, new ArrayList<>());TreeBean t5 = new TreeBean(5, "白云区", 3, new ArrayList<>());TreeBean t6 = new TreeBean(6, "黄浦区", 3, new ArrayList<>());TreeBean t7 = new TreeBean(7, "白云街道", 5, new ArrayList<>());TreeBean t8 = new TreeBean(8, "深圳市", 1, new ArrayList<>());TreeBean t9 = new TreeBean(9, "宝安区", 8, new ArrayList<>());TreeBean t10 = new TreeBean(10, "福田区", 8, new ArrayList<>());TreeBean t11 = new TreeBean(11, "南山区", 8, new ArrayList<>());TreeBean t12 = new TreeBean(12, "南山街道", 11, new ArrayList<>());TreeBean t13 = new TreeBean(13, "芙蓉区", 4, new ArrayList<>());TreeBean t14 = new TreeBean(14, "岳麓区", 4, new ArrayList<>());TreeBean t15 = new TreeBean(15, "开福区", 4, new ArrayList<>());TreeBean t16 = new TreeBean(16, "岳阳市", 2, new ArrayList<>());TreeBean t17 = new TreeBean(17, "岳麓街道", 14, new ArrayList<>());list.add(t1);list.add(t2);list.add(t3);list.add(t4);list.add(t5);list.add(t6);list.add(t7);list.add(t8);list.add(t9);list.add(t10);list.add(t11);list.add(t12);list.add(t13);list.add(t14);list.add(t15);list.add(t16);list.add(t17);return list;}
}
实现类
/*** 方式一:Stream流递归实现遍历树形结构*/public static void main(String[] args) {//获取数据List<TreeBean> treeBeans = new TreeBean().initializationData();//获取父节点List<TreeBean> collect = treeBeans.stream().filter(t -> t.getParentId() == 0).map(m -> {m.setChildList(getChildren(m, treeBeans));return m;}).collect(Collectors.toList());System.out.println(JSON.toJSONString(collect));}/*** 递归查询子节点* @param root 根节点* @param all 所有节点* @return 根节点信息*/public static List<TreeBean> getChildren(TreeBean root, List<TreeBean> all) {List<TreeBean> children = all.stream().filter(t -> {return Objects.equals(t.getParentId(), root.getId());}).map(m -> {m.setChildList(getChildren(m, all));return m;}).collect(Collectors.toList());return children;}