0%

【拓展】树形结构数据

关于数据库树形结构数据的读取以及使用

一、创建数据库

数据库主要3个字段:id, pid, name
id为:编号
pid为:父节点编号
name:节点名称


二、打印树形结构数据

在控制台中打印出树形结构

2.1 创建Bean类

1
2
3
4
5
6
7
8
9
//导入了lombok进行快速创建
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Tree {
private String id;
private String pid;
private String name;
}

2.2 整合Mybatis使用数据库

具体使用方法不多介绍,大致说一下步骤(本人使用SpringBoot项目)

  • (1)application.yaml配置文件连接数据库,并配置Mapper映射文件的位置
1
2
3
4
5
6
7
8
9
10
spring:
datasource:
username: root
password: 123
url: jdbc:mysql://localhost:3306/treenode?serverTimezone=GMT%2B8
driver-class-name: com.mysql.cj.jdbc.Driver

#Mybatis配置
mybatis:
mapper-locations: classpath:mapper/*.xml
  • (2)创建dao层接口
1
2
3
4
5
@Mapper
@Repository
public interface TreeMapper {
public List<Tree> queryAllTreeNode();
}
  • (3)创建Mapper映射文件
1
2
3
4
5
6
7
8
9
10
11
<?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.letere.dao.TreeMapper">
<select id="queryAllTreeNode" resultType="com.letere.pojo.Tree">
select *
from `tree`
</select>
</mapper>

2.3 创建工具类打印树形结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
public class PrintTreeUtil {
//寻找父节点
private static List<Tree> findFather(List<Tree> trees){
List<Tree> father = new ArrayList<>();
for (Tree tree : trees){
if (tree.getPid() == null){
father.add(tree);
}
}
return father;
}

//寻找父节点的子节点
private static List<Tree> findChild(Tree tree, List<Tree> trees){
List<Tree> child = new ArrayList<>();
for (Tree t : trees){
if (tree.getId().equals(t.getPid())){
child.add(t);
}
}
return child;
}

//递归打印一个节点下的所有子节点
private static void printTree(Tree tree, List<Tree> trees, String priex){ //priex:前缀
List<Tree> child = findChild(tree, trees);
if (child != null){//存在子节点
for (Tree c : child){
System.out.println(priex + "|--" + c.getName());
printTree(c, trees, priex + " "); //递归
}
}
}

//打印树形结构
public static void printTreePlus(List<Tree> trees){
List<Tree> father = findFather(trees);

for (Tree f : father){
System.out.println(f.getName()); //打印父节点
printTree(f, trees, " "); //打印该父节点下的所有子节点
}
}
}

2.4 方法测试及结果

1
2
3
4
5
@Test
void test(){
List<Tree> trees = treeMapper.queryAllTreeNode(); //获取数据库所有节点
PrintTreeUtil.printTreePlus(trees); //按树形结构打印
}

三、关联树形结构数据

3.1 创建JavaBean

要创建一个父子节点有关联的Bean

1
2
3
4
5
6
7
8
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Tree2 {
private String id;
private String name;
private List<Tree2> child; //关联子节点数据
}

3.2 Service实现关联

实现思路和上面的打印树形结构思路基本一致,只是从打印变成赋值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
@Service
public class TreeService implements TreeMapper {

@Autowired
TreeMapper treeMapper;

@Override
public List<Tree> queryAllTreeNode() {
return treeMapper.queryAllTreeNode();
}

//寻找父节点
private List<Tree> findFather(List<Tree> trees){
List<Tree> father = new ArrayList<>();
for (Tree tree : trees){
if (tree.getPid() == null){
father.add(tree);
}
}
return father;
}

//寻找该父节点的子节点
private List<Tree> findChild(Tree tree, List<Tree> trees){
List<Tree> child = new ArrayList<>();
for (Tree t : trees){
if (tree.getId().equals(t.getPid())){
child.add(t);
}
}
return child;
}

//递归关联一个父节点下的所有子节点
private List<Tree2> addTree(Tree tree, List<Tree> trees){
List<Tree> childs = findChild(tree, trees);
List<Tree2> nodes = new ArrayList<>();
if (childs != null){//子节点存在
for (Tree c : childs){
if (c.getPid().equals(tree.getId())){
Tree2 node = new Tree2(c.getId(), c.getName(), addTree(c, trees)); //将Tree类型数据转变为Tree2类型,并递归寻找自己的子节点
nodes.add(node); //将Tree2类型数据添加到列表中
}
}
}
return nodes;
}

//递归关联父节点与子节点
public List<Tree2> treeNodes(){
List<Tree> trees = queryAllTreeNode();
List<Tree> father = findFather(trees);
List<Tree2> nodes = new ArrayList<>();

for (Tree f : father){
Tree2 node = new Tree2(f.getId(), f.getName(), addTree(f, trees)); //递归寻找自己的子节点,并变成Tree2类型数据
nodes.add(node);
}
return nodes;
}
}

3.3 方法测试及结果

1
2
3
4
5
6
7
8
@Autowired
TreeService treeService;

@Test
void test3(){
List<Tree2> nodes = treeService.treeNodes();
System.out.println(nodes);
}