目录
前言:
开发前准备:
数据库:
实体类:
VO对象:
代码实现:
Controller层:
Service层:
运行结果:
第二种
前言:
在日常的开发或者工作需求中,我们会用到树形结构数据。树形结构是一个比较常用的数据类型,一般多用于查询包含父子类关系的数据。我们常常通过父级id和层级作为标识,是数据更加形象,从而进行树形数据的展示。
开发前准备:
数据库:
-- ----------------------------
-- Table structure for dev_type
-- ----------------------------
DROP TABLE IF EXISTS `dev_type`;
CREATE TABLE `dev_type` (
`id` int(50) NOT NULL,
`name` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '名称',
`level` tinyint(3) NULL DEFAULT NULL COMMENT '层级 1 2 3',
`parent_id` int(50) NULL DEFAULT NULL COMMENT '父级id',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of dev_type
-- ----------------------------
INSERT INTO `dev_type` VALUES (110, '长安区', 3, 119);
INSERT INTO `dev_type` VALUES (119, '石家庄市', 2, 10086);
INSERT INTO `dev_type` VALUES (10010, '中原区', 3, 456789);
INSERT INTO `dev_type` VALUES (10086, '河北省', 1, NULL);
INSERT INTO `dev_type` VALUES (12313, '高新区', 3, 456789);
INSERT INTO `dev_type` VALUES (123456, '河南省', 1, NULL);
INSERT INTO `dev_type` VALUES (456789, '郑州市', 2, 123456);
SET FOREIGN_KEY_CHECKS = 1;
实体类:
@Data
@TableName("dev_type")
@JsonInclude(JsonInclude.Include.NON_EMPTY)
public class DevType {
private static final long serialVersionUID = 1L;
@JsonSerialize(using = ToStringSerializer.class)
private Long id;
/**
* 名称
*/
@ApiModelProperty("名称")
private String name;
/**
* 等级(1 ,2,3)
*/
@ApiModelProperty("等级(1 ,2,3)")
private String level;
/**
* 父级id
*/
@ApiModelProperty("父级id")
private Long parentId;
}
VO对象:
@Data
@JsonInclude(JsonInclude.Include.NON_EMPTY)
public class TreeNode extends DevType {
private static final long serialVersionUID = 1L;
@ApiModelProperty("子节点")
private List<TreeNode> child;
}
代码实现:
Controller层:
@GetMapping("/newTree/list")
@ApiOperation(value = "树形结构列表", notes = "传入devType")
public List<TreeNode> newTreeList(DevType devType) {
List<TreeNode> pages = devTypeService.newTreeList(devType);
return pages;
}
Service层:
/**
* id和 parentId 有对应关系 父级id 为子级的 parentId
* 根据level也进行区分层级
* 什么也不传 按照树形结构查出所有数据
* @param devType
* @return
*/
@Override
public List<TreeNode> newTreeList(DevType devType) {
if (devType == null || (devType.getLevel() == null && devType.getId() == null && devType.getParentId() == null)) {
devType.setLevel("1");
}
QueryWrapper<DevType> queryWrapper = new QueryWrapper<>();
// 构造查询条件
queryWrapper.eq(devType.getId() != null, "id", devType.getId())
.eq(StringUtils.isNotBlank(devType.getLevel()), "level", devType.getLevel())
.eq(devType.getParentId() != null, "parent_id", devType.getParentId());
return getTree(queryWrapper);
}
private List<TreeNode> getTree(QueryWrapper<DevType> queryWrapper) {
List<DevType> list = this.list(queryWrapper);
List<TreeNode> voList = new ArrayList<>(list.size());
for (DevType child : list) {
TreeNode childVO = new TreeNode();
BeanUtils.copyProperties(child, childVO);
QueryWrapper<DevType> childQueryWrapper = new QueryWrapper<>();
childQueryWrapper.eq("parent_id", child.getId());
childVO.setChild(getTree(childQueryWrapper));
voList.add(childVO);
}
return voList;
}
运行结果:
[
{
"id": "10086",
"name": "河北省",
"level": "1",
"child": [
{
"id": "119",
"name": "石家庄市",
"level": "2",
"parentId": 10086,
"child": [
{
"id": "110",
"name": "长安区",
"level": "3",
"parentId": 119
}
]
}
]
},
{
"id": "123456",
"name": "河南省",
"level": "1",
"child": [
{
"id": "456789",
"name": "郑州市",
"level": "2",
"parentId": 123456,
"child": [
{
"id": "10010",
"name": "中原区",
"level": "3",
"parentId": 456789
},
{
"id": "12313",
"name": "高新区",
"level": "3",
"parentId": 456789
}
]
}
]
}
]
第二种:
@GetMapping("/tree/list")
@ApiOperationSupport(order = 2)
@ApiOperation(value = "树形结构列表", notes = "")
public R<List<TreeNode>> getDataList() {
List<DevType> pages = devTypeService.list();
List<TreeNode> devTypes = buildTree(pages, null);
return R.data(devTypes);
}
private List<TreeNode> buildTree(List<DevType> devTypes, Long parentId) {
List<TreeNode> tree = new ArrayList<>();
for (DevType devType : devTypes) {
if (devType.getParentId() == parentId) {
TreeNodetreeNode = new TreeNode();
BeanUtils.copyProperties(devType,treeNode);
// 递归构建子树
List<TreeNode> children = buildTree(devTypes, devType.getId());
treeNode.setChildren(children);
tree.add(treeNode);
}
}
return tree;
}
第三种:
通过stream获取: 文章来源:https://www.toymoban.com/news/detail-658650.html
/**
* 使用stream获取树形结构
* @return
*/
@GetMapping("/new/tree")
@ApiOperationSupport(order = 2)
@ApiOperation(value = "树形结构列表", notes = "传入devType")
public R<List<TreeNode>> newTree() {
List<DevType> pages = devTypeService.list(); //1
List<TreeNode> list = pages.stream().map(devType -> {
TreeNode vo = new TreeNode();
BeanUtils.copyProperties(devType, vo);
return vo;
}).collect(Collectors.toList()); //2
//1、2 两部可以通过mapper方法实现,直接转换成VO数据
List<TreeNode> TreeMenu = list.stream().filter(m -> m.getParentId() == null).map(
(m) -> {
m.setChildren(getChildrens(m, list));
return m;
}
).collect(Collectors.toList());
return R.data(TreeMenu);
}
private List<TreeNode> getChildrens(TreeNode root, List<TreeNode> all) {
List<TreeNode> children = all.stream().filter(m -> {
return Objects.equals(m.getParentId(), root.getId());
}).map(
(m) -> {
m.setChildren(getChildrens(m, all));
return m;
}
).collect(Collectors.toList());
return children;
}
在这里,我们需要先搞清楚对应的父子关系,只有捋顺了关系之后才能进行代码的书写。第一种方式是我们什么都不传的情况下,默认查出的是全部的数据。如果想要查某一条下面具体的子类,可以传入对应的id和层级level。第二种是查出全部的树形结构数据。在此特作分享,给大家提供不一样的思路。文章来源地址https://www.toymoban.com/news/detail-658650.html
到了这里,关于Java获取树形结构数据的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!