java返回树形结构的正确姿势
业务场景
通常我们前端需要一个树形的导航菜单或者分类菜单,如后台权限管理中的权限树,亦或者下面例子中商城系统的商品分类多级菜单(一般为三级菜单)
数据库设计
数据库设计,采用parentId来指向自己的父级菜单,如:
CREATE TABLE `pms_category` (
`cat_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '分类id',
`name` char(50) DEFAULT NULL COMMENT '分类名称',
`parent_cid` bigint(20) DEFAULT NULL COMMENT '父分类id',
`cat_level` int(11) DEFAULT NULL COMMENT '层级',
`show_status` tinyint(4) DEFAULT NULL COMMENT '是否显示[0-不显示,1显示]',
`sort` int(11) DEFAULT NULL COMMENT '排序',
`icon` char(255) DEFAULT NULL COMMENT '图标地址',
`product_unit` char(50) DEFAULT NULL COMMENT '计量单位',
`product_count` int(11) DEFAULT NULL COMMENT '商品数量',
PRIMARY KEY (`cat_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1433 DEFAULT CHARSET=utf8mb4 COMMENT='商品三级分类';
java组装树形结构
之前的做法是通过sql自连接来查出树形结构数据,但是效率不高,我们知道单表查询效率是最高的,我们可以一次查出所有数据,通过java8的新特性 stream来处理数据,stream是通过CPU计算实现,效率极高,具体用法可以参考:
Java 8新特性之 Lambd和StreamAPI
下面是处理数据的两个主要方法:
@Override
public List<CategoryEntity> listWithTree() {
// 1. 先查出所有分类数据
List<CategoryEntity> categories = baseMapper.selectList(null);
// 2. 找出所有一级分类
// 在映射到每个一级分类 添加它的子分类类
return categories.stream()
.filter(o -> o.getParentCid() == 0)
// 给每个一级分类加子分类
.peek(o -> o.setChildrens(getChildCategoryList(o, categories)))
// 排序
.sorted(Comparator.comparingInt(CategoryEntity::getSort))
// 收集
.collect(Collectors.toList());
}
// 根据当前分类 找出子类, 并通过递归找出子类的子类
private List<CategoryEntity> getChildCategoryList(CategoryEntity currMenu, List<CategoryEntity> categories) {
return categories.stream().filter(o -> o.getParentCid().equals(currMenu.getCatId()))
.peek(o -> o.setChildrens(getChildCategoryList(o, categories)))
.sorted(Comparator.comparingInt(CategoryEntity::getSort))
.collect(Collectors.toList());
}
实体类变动
- 为了拼接子菜单,需要将实体类增加一个属性childrens
- 排序时需要用到sort属性,该字段在数据库可能为null,采用三元运算将其默认为0,防止排序异常
@TableField(exist = false)
private List<CategoryEntity> childrens;
public Integer getSort() {
return sort == null ? 0 : sort;
}
返回数据效果
业务场景
通常我们前端需要一个树形的导航菜单或者分类菜单,如后台权限管理中的权限树,亦或者下面例子中商城系统的商品分类多级菜单(一般为三级菜单)
数据库设计
数据库设计,采用parentId来指向自己的父级菜单,如:
CREATE TABLE `pms_category` (
`cat_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '分类id',
`name` char(50) DEFAULT NULL COMMENT '分类名称',
`parent_cid` bigint(20) DEFAULT NULL COMMENT '父分类id',
`cat_level` int(11) DEFAULT NULL COMMENT '层级',
`show_status` tinyint(4) DEFAULT NULL COMMENT '是否显示[0-不显示,1显示]',
`sort` int(11) DEFAULT NULL COMMENT '排序',
`icon` char(255) DEFAULT NULL COMMENT '图标地址',
`product_unit` char(50) DEFAULT NULL COMMENT '计量单位',
`product_count` int(11) DEFAULT NULL COMMENT '商品数量',
PRIMARY KEY (`cat_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1433 DEFAULT CHARSET=utf8mb4 COMMENT='商品三级分类';
java组装树形结构
之前的做法是通过sql自连接来查出树形结构数据,但是效率不高,我们知道单表查询效率是最高的,我们可以一次查出所有数据,通过java8的新特性 stream来处理数据,stream是通过CPU计算实现,效率极高,具体用法可以参考:
Java 8新特性之 Lambd和StreamAPI
下面是处理数据的两个主要方法:
@Override
public List<CategoryEntity> listWithTree() {
// 1. 先查出所有分类数据
List<CategoryEntity> categories = baseMapper.selectList(null);
// 2. 找出所有一级分类
// 在映射到每个一级分类 添加它的子分类类
return categories.stream()
.filter(o -> o.getParentCid() == 0)
// 给每个一级分类加子分类
.peek(o -> o.setChildrens(getChildCategoryList(o, categories)))
// 排序
.sorted(Comparator.comparingInt(CategoryEntity::getSort))
// 收集
.collect(Collectors.toList());
}
// 根据当前分类 找出子类, 并通过递归找出子类的子类
private List<CategoryEntity> getChildCategoryList(CategoryEntity currMenu, List<CategoryEntity> categories) {
return categories.stream().filter(o -> o.getParentCid().equals(currMenu.getCatId()))
.peek(o -> o.setChildrens(getChildCategoryList(o, categories)))
.sorted(Comparator.comparingInt(CategoryEntity::getSort))
.collect(Collectors.toList());
}
实体类变动
- 为了拼接子菜单,需要将实体类增加一个属性childrens
- 排序时需要用到sort属性,该字段在数据库可能为null,采用三元运算将其默认为0,防止排序异常
@TableField(exist = false)
private List<CategoryEntity> childrens;
public Integer getSort() {
return sort == null ? 0 : sort;
}
返回数据效果

java返回树形结构的正确姿势的更多相关文章
- Java实现树形结构的数据转Json格式
在项目中难免会用到树形结构,毕竟这是一种常用的组织架构.楼主这里整理了两个实现的版本,可以直接拿来使用,非常方便. 楼主没有单独建项目,直接在以前的一个Demo上实现的.第一种,看下面代码: pack ...
- Java创建树形结构算法实例
在JavaWeb的相关开发中经常会涉及到多级菜单的展示,为了方便菜单的管理需要使用数据库进行支持,本例采用相关算法讲数据库中的条形记录进行相关组装和排序讲菜单组装成树形结构. 首先是需要的JavaBe ...
- java 实现树形结构
package tree; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Font; import java ...
- JAVA获取树形结构
package com.nnmzkj.common.dto; import lombok.Data; import java.io.Serializable;import java.util.Arra ...
- java后台树形结构展示---懒加载
一.数据库设计 二.实体类:entity import com.joyoung.cloud.security.common.validatedGroup.Add;import com.joyoung. ...
- 2020年大厂Java面试前复习的正确姿势(800+面试题附答案解析)
前言 个人觉得面试也像是一场全新的征程,失败和胜利都是平常之事.所以,劝各位不要因为面试失败而灰心. 丧失斗志.也不要因为面试通过而沾沾自喜,等待你的将是更美好的未来,继续加油! 本篇分享的面试题内容 ...
- 使用 Java8 Optional 的正确姿势(转)
我们知道 Java 8 增加了一些很有用的 API, 其中一个就是 Optional. 如果对它不稍假探索, 只是轻描淡写的认为它可以优雅的解决 NullPointException 的问题, 于是代 ...
- [转] 使用 Java8 Optional 的正确姿势
[From] https://unmi.cc/proper-ways-of-using-java8-optional/ 我们知道 Java 8 增加了一些很有用的 API, 其中一个就是 Option ...
- Java编程:将具有父子关系的数据库表数据转换为树形结构,支持无限层级
在平时的开发工作中,经常遇到这样一个场景,在数据库中存储了具有父子关系的数据,需要将这些数据以树形结构的形式在界面上进行展示.本文的目的是提供了一个通用的编程模型,解决将具有父子关系的数据转换成树形结 ...
随机推荐
- Taurus.MVC 2.3.4 :WebAPI 文档集成测试功能升级:WebAPI批量自动化测试功能。
前言: 最近升级了一下Taurus.MVC,现在最新版本是:Taurus.MVC 2.3.4,源码版本和nuget同步. 下面分三个步骤介绍下新版本的WebAPI批量自动化测试功能. 1.启用WebA ...
- 【六省联考2017】组合数问题 题解(矩阵快速幂优化DP)
题目链接 题目大意:求$(\sum\limits_{i=0}^n C_{nk}^{ik+r})\ mod \ p$的值. --------------------- 讲真,一开始看到这个题我都没往DP ...
- ios 生成字母加数字的随机数
文章来自:http://blog.csdn.net/baidu_25743639/article/details/73801700 近期项目第三方登录之后默认创建账号和密码,就用随机数生产,这里只需要 ...
- python3.1for循环及应用
#给定范围,进行循环for i in range (0,5): print(i) #对序列进行遍历list1=[1,2,3,4,5]for i in list1: print(i+1) #对元组进行遍 ...
- 安卓APP开发的初步了解
今天成功安装了Android Studio 并且对APP的开发框架结构进行了初步了解 如上图:app基本结构情况 下面来仔细解释一下各个方面目录的作用 首先 manifests目录:包含Android ...
- 【项目实战】sass使用基础篇(上)
Sass是一种CSS预处理语言.CSS预处理语言是一种新的专门的编程语言,编译后形成正常的css文件,为css增加一些编程特性,无需考虑浏览器的兼容性(完全兼容css3),让css更加简洁.适应性更强 ...
- xadmin 安装
xadmin 安装 环境(一定要一样) Python 3.6.2 Django 2.0 安装 pip install django==2.0, 指定特定的版本 pip install https:// ...
- 解决用anaconda安装scrapy后,在使用scrapy时报错
python版本为3.7 因为用anaconda安装scrapy非常方便,会自动下载所依赖的包, 所以就使用anaconda安装scrapy, 非常舒服,安装很成功 conda install scr ...
- do...while循环语句(水仙花)
#define _CRT_SECURE_NO_WARNINGS#include<stdio.h>#include<string.h>#include<stdlib.h&g ...
- 【工具】OSS阿里云存储服务--超级简单--个人还是觉得Fastdfs好玩
介绍 阿里云对象存储服务(Object Storage Service,简称 OSS)为您提供基于网络的数据存取服务. 使用 OSS,您可以通过网络随时存储和调用包括文本.图片.音频和视频等在内的各种 ...