在平时的开发工作中,经常遇到这样一个场景,在数据库中存储了具有父子关系的数据,需要将这些数据以树形结构的形式在界面上进行展示。本文的目的是提供了一个通用的编程模型,解决将具有父子关系的数据转换成树形结构的问题。如有不正之处,欢迎大家批评指正。

编程模型

我们以北京行政区划为例,讲解整个模型。

北京市:市辖区 县

市辖区:东城区 西城区 朝阳区 丰台区 石景山区 海淀区 门头沟区 房山区 通州区 顺义区 昌平区 大兴区 怀柔区 平谷区

县:密云县 延庆县

UML类图如下:

Tree结构

TreeNode:定义树的节点对象

nodeId:树节点Id。

nodeName:树节点名称。

parentNodeId:树节点父Id。

orderNum:节点在树中的排序号,在同一节点下进行排序。

level:当前树节点所在的层级,根节点为第一层。

parent:当前树节点的父节点。

children:当前树节点的儿子节点。

allChildren:当前树节点的子孙节点。

ITree:定义树对象要实现的方法。

getTree():以 List 形式返回树的所有的 TreeNode 对象。

getRoot():以 List 形式返回树的根节点,可能是一个或者多个。

getTreeNode(String nodeId):根据 nodeId 返回对应的 TreeNode 对象。

Tree:实现 ITree 接口,提供树的完整功能。

getTree():以 List 形式返回树的所有的 TreeNode 对象。

getRoot():以 List 形式返回树的根节点,可能是一个或者多个。

getTreeNode(String nodeId):根据 nodeId 返回对应的 TreeNode 对象。

ITreeNode:定义模板方法,构造树形结构的类要实现该接口,Tree 通过调用该接口中的方法获取 nodeId nodeName parentNodeId orderNum 数据。

getNodeId():获取树节点Id。

getNodeName():获取树节点名称。

getParentNodeId():获取树节点父Id。

getOrderNum():获取节点在树中的排序号,在同一节点下进行排序。

Org:定义行政区划类,实现 ItreeNode 接口。

---------------------

在平时的开发工作中,经常遇到这样一个场景,在数据库中存储了具有父子关系的数据,需要将这些数据以树形结构的形式在界面上进行展示。本文的目的是提供了一个通用的编程模型,解决将具有父子关系的数据转换成树形结构的问题。如有不正之处,欢迎大家批评指正。

编程模型

我们以北京行政区划为例,讲解整个模型。

北京市:市辖区 县

市辖区:东城区 西城区 朝阳区 丰台区 石景山区 海淀区 门头沟区 房山区 通州区 顺义区 昌平区 大兴区 怀柔区 平谷区

县:密云县 延庆县

UML类图如下:

Tree结构

TreeNode:定义树的节点对象

nodeId:树节点Id。

nodeName:树节点名称。

parentNodeId:树节点父Id。

orderNum:节点在树中的排序号,在同一节点下进行排序。

level:当前树节点所在的层级,根节点为第一层。

parent:当前树节点的父节点。

children:当前树节点的儿子节点。

allChildren:当前树节点的子孙节点。

ITree:定义树对象要实现的方法。

getTree():以 List 形式返回树的所有的 TreeNode 对象。

getRoot():以 List 形式返回树的根节点,可能是一个或者多个。

getTreeNode(String nodeId):根据 nodeId 返回对应的 TreeNode 对象。

Tree:实现 ITree 接口,提供树的完整功能。

getTree():以 List 形式返回树的所有的 TreeNode 对象。

getRoot():以 List 形式返回树的根节点,可能是一个或者多个。

getTreeNode(String nodeId):根据 nodeId 返回对应的 TreeNode 对象。

ITreeNode:定义模板方法,构造树形结构的类要实现该接口,Tree 通过调用该接口中的方法获取 nodeId nodeName parentNodeId orderNum 数据。

getNodeId():获取树节点Id。

getNodeName():获取树节点名称。

getParentNodeId():获取树节点父Id。

getOrderNum():获取节点在树中的排序号,在同一节点下进行排序。

Org:定义行政区划类,实现 ItreeNode 接口。

实现代码

TreeNode类:

package com.ips.tree;

import java.util.ArrayList;

import java.util.List;

import com.alibaba.fastjson.annotation.JSONField;

/**

*

Title: 树节点

*

Description:一棵树由许多包含父子关系的节点组成

* @author  liuzhibo

* @date    2017年1月18日

*/

public class TreeNode {

//树节点ID

@JSONField(ordinal=1)

private String nodeId;

//树节点名称

@JSONField(ordinal=2)

private String nodeName;

//父节点ID

@JSONField(ordinal=3)

private String parentNodeId;

//节点在树中的排序号

@JSONField(ordinal=4)

private int orderNum;

//节点所在的层级

@JSONField(ordinal=5)

private int level;

private TreeNode parent;

//当前节点的二子节点

@JSONField(ordinal=6)

private List children = new ArrayList();

//当前节点的子孙节点

private List allChildren = new ArrayList();

public TreeNode(ITreeNode obj){

this.nodeId = obj.getNodeId();

this.nodeName = obj.getNodeName();

this.parentNodeId = obj.getNodeParentId();

this.orderNum = obj.getOrderNum();

}

public void addChild(TreeNode treeNode){

this.children.add(treeNode);

}

public void removeChild(TreeNode treeNode){

this.children.remove(treeNode);

}

public String getNodeId() {

return nodeId;

}

public void setNodeId(String nodeId) {

this.nodeId = nodeId;

}

public String getNodeName() {

return nodeName;

}

public void setNodeName(String nodeName) {

this.nodeName = nodeName;

}

public String getParentNodeId() {

return parentNodeId;

}

public void setParentNodeId(String parentNodeId) {

this.parentNodeId = parentNodeId;

}

public int getLevel() {

return level;

}

public void setLevel(int level) {

this.level = level;

}

public TreeNode getParent() {

return parent;

}

public void setParent(TreeNode parent) {

this.parent = parent;

}

public List getChildren() {

return children;

}

public void setChildren(List children) {

this.children = children;

}

public int getOrderNum() {

return orderNum;

}

public void setOrderNum(int orderNum) {

this.orderNum = orderNum;

}

public List getAllChildren() {

if(this.allChildren.isEmpty()){

for(TreeNode treeNode : this.children){

this.allChildren.add(treeNode);

this.allChildren.addAll(treeNode.getAllChildren());

}

}

return this.allChildren;

}

}

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

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

ITree接口:

package com.ips.tree;

import java.util.List;

public interface ITree {

public List getTree();

public List getRoot();

public TreeNode getTreeNode(String nodeId);

}

1

2

3

4

5

6

7

8

9

Tree类:

package com.ips.tree;

import java.util.ArrayList;

import java.util.HashMap;

import java.util.Iterator;

import java.util.List;

public class Tree implements ITree {

private HashMap treeNodesMap = new HashMap();

private List treeNodesList = new ArrayList();

public Tree(List list){

initTreeNodeMap(list);

initTreeNodeList();

}

private void initTreeNodeMap(List list){

TreeNode treeNode = null;

for(ITreeNode item : list){

treeNode = new TreeNode(item);

treeNodesMap.put(treeNode.getNodeId(), treeNode);

}

Iterator iter = treeNodesMap.values().iterator();

TreeNode parentTreeNode = null;

while(iter.hasNext()){

treeNode = iter.next();

if(treeNode.getParentNodeId() == null || treeNode.getParentNodeId() == ""){

continue;

}

parentTreeNode = treeNodesMap.get(treeNode.getParentNodeId());

if(parentTreeNode != null){

treeNode.setParent(parentTreeNode);

parentTreeNode.addChild(treeNode);

}

}

}

private void initTreeNodeList(){

if(treeNodesList.size() > 0){

return;

}

if(treeNodesMap.size() == 0){

return;

}

Iterator iter = treeNodesMap.values().iterator();

TreeNode treeNode = null;

while(iter.hasNext()){

treeNode = iter.next();

if(treeNode.getParent() == null){

this.treeNodesList.add(treeNode);

this.treeNodesList.addAll(treeNode.getAllChildren());

}

}

}

@Override

public List getTree() {

return this.treeNodesList;

}

@Override

public List getRoot() {

List rootList = new ArrayList();

if (this.treeNodesList.size() > 0) {

for (TreeNode node : treeNodesList) {

if (node.getParent() == null)

rootList.add(node);

}

}

return rootList;

}

@Override

public TreeNode getTreeNode(String nodeId) {

return this.treeNodesMap.get(nodeId);

}

}

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

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

ITreeNode 接口:

package com.ips.tree;

public interface ITreeNode {

public String getNodeId();

public String getNodeName();

public String getNodeParentId();

public Integer getOrderNum();

}

1

2

3

4

5

6

7

8

Org 类:

package com.ips.tree;

public class Org implements ITreeNode {

private String uuid;

private String parentId;

private String name;

private Integer orderNum;

private String code;

private String type;

public Org(){

}

public Org(String uuid, String parentId, String name, Integer orderNum, String code, String type){

this.uuid = uuid;

this.parentId = parentId;

this.name = name;

this.orderNum = orderNum;

this.code = code;

this.type = type;

}

@Override

public String getNodeId() {

return this.uuid;

}

@Override

public String getNodeName() {

return this.name;

}

@Override

public String getNodeParentId() {

return this.parentId;

}

@Override

public Integer getOrderNum() {

return this.orderNum;

}

public String getUuid() {

return uuid;

}

public void setUuid(String uuid) {

this.uuid = uuid;

}

public String getParentId() {

return parentId;

}

public void setParentId(String parentId) {

this.parentId = parentId;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public String getCode() {

return code;

}

public void setCode(String code) {

this.code = code;

}

public String getType() {

return type;

}

public void setType(String type) {

this.type = type;

}

public void setOrderNum(Integer orderNum) {

this.orderNum = orderNum;

}

}

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

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

TreeDemo 类:执行该类的 main 方法,查看效果。

package com.ips.tree;

import java.util.ArrayList;

import java.util.List;

import com.alibaba.fastjson.JSONObject;

import com.alibaba.fastjson.serializer.SimplePropertyPreFilter;

public class TreeDemo {

public static void main(String[] args) {

Tree tree = new Tree(genOrgList());

TreeNode treeNode = tree.getTreeNode("2");

SimplePropertyPreFilter filter = new SimplePropertyPreFilter(); // 构造方法里,也可以直接传需要序列化的属性名字

filter.getExcludes().add("parent");

filter.getExcludes().add("allChildren");

String data = JSONObject.toJSONString(treeNode, filter);

System.out.println(data);

}

public static List genOrgList(){

List list = new ArrayList();

Org org = new Org("2", "1", "北京市", 2, "110000", "2");

list.add(org);

org = new Org("3", "2", "市辖区", 3, "110100", "3");

list.add(org);

org = new Org("4", "3", "东城区", 4, "110101", "4");

list.add(org);

org = new Org("5", "3", "东城区", 5, "110102", "4");

list.add(org);

org = new Org("6", "3", "东城区", 6, "110105", "4");

list.add(org);

org = new Org("7", "3", "东城区", 7, "110106", "4");

list.add(org);

org = new Org("8", "3", "东城区", 8, "110107", "4");

list.add(org);

org = new Org("9", "3", "东城区", 9, "110108", "4");

list.add(org);

org = new Org("10", "3", "东城区", 10, "110109", "4");

list.add(org);

org = new Org("11", "3", "东城区", 11, "110111", "4");

list.add(org);

org = new Org("12", "3", "东城区", 12, "110112", "4");

list.add(org);

org = new Org("13", "3", "东城区", 13, "110113", "4");

list.add(org);

org = new Org("14", "3", "东城区", 14, "110114", "4");

list.add(org);

org = new Org("15", "3", "东城区", 15, "110115", "4");

list.add(org);

org = new Org("16", "3", "东城区", 16, "110116", "4");

list.add(org);

org = new Org("17", "3", "东城区", 17, "110117", "4");

list.add(org);

org = new Org("18", "2", "县", 3, "110200", "3");

list.add(org);

org = new Org("19", "18", "密云县", 19, "110228", "4");

list.add(org);

org = new Org("20", "18", "延庆县", 20, "110229", "4");

list.add(org);

return list;

}

}

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

62

63

64

65

66

执行结果如下:

{

"nodeId": "2",

"nodeName": "北京市",

"parentNodeId": "1",

"orderNum": 2,

"level": 0,

"children": [{

"nodeId": "18",

"nodeName": "县",

"parentNodeId": "2",

"orderNum": 3,

"level": 0,

"children": [{

"nodeId": "19",

"nodeName": "密云县",

"parentNodeId": "18",

"orderNum": 19,

"level": 0,

"children": []

},

{

"nodeId": "20",

"nodeName": "延庆县",

"parentNodeId": "18",

"orderNum": 20,

"level": 0,

"children": []

}]

},

{

"nodeId": "3",

"nodeName": "市辖区",

"parentNodeId": "2",

"orderNum": 3,

"level": 0,

"children": [{

"nodeId": "17",

"nodeName": "东城区",

"parentNodeId": "3",

"orderNum": 17,

"level": 0,

"children": []

},

{

"nodeId": "15",

"nodeName": "东城区",

"parentNodeId": "3",

"orderNum": 15,

"level": 0,

"children": []

},

{

"nodeId": "16",

"nodeName": "东城区",

"parentNodeId": "3",

"orderNum": 16,

"level": 0,

"children": []

},

{

"nodeId": "13",

"nodeName": "东城区",

"parentNodeId": "3",

"orderNum": 13,

"level": 0,

"children": []

},

{

"nodeId": "14",

"nodeName": "东城区",

"parentNodeId": "3",

"orderNum": 14,

"level": 0,

"children": []

},

{

"nodeId": "11",

"nodeName": "东城区",

"parentNodeId": "3",

"orderNum": 11,

"level": 0,

"children": []

},

{

"nodeId": "12",

"nodeName": "东城区",

"parentNodeId": "3",

"orderNum": 12,

"level": 0,

"children": []

},

{

"nodeId": "10",

"nodeName": "东城区",

"parentNodeId": "3",

"orderNum": 10,

"level": 0,

"children": []

},

{

"nodeId": "7",

"nodeName": "东城区",

"parentNodeId": "3",

"orderNum": 7,

"level": 0,

"children": []

},

{

"nodeId": "6",

"nodeName": "东城区",

"parentNodeId": "3",

"orderNum": 6,

"level": 0,

"children": []

},

{

"nodeId": "5",

"nodeName": "东城区",

"parentNodeId": "3",

"orderNum": 5,

"level": 0,

"children": []

},

{

"nodeId": "4",

"nodeName": "东城区",

"parentNodeId": "3",

"orderNum": 4,

"level": 0,

"children": []

},

{

"nodeId": "9",

"nodeName": "东城区",

"parentNodeId": "3",

"orderNum": 9,

"level": 0,

"children": []

},

{

"nodeId": "8",

"nodeName": "东城区",

"parentNodeId": "3",

"orderNum": 8,

"level": 0,

"children": []

}]

}]

}

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

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

注:该示例中使用了 alibaba 的 fastjson 实现类对象序列化,maven 依赖如下:

com.alibaba

fastjson

1.2.20

---------------------

作者:zhiboer

来源:CSDN

原文:https://blog.csdn.net/claram/article/details/54616485

版权声明:本文为博主原创文章,转载请附上博文链接!

java父子表_Java编程:将具有父子关系的数据库表数据转换为树形结构,支持无限层级...相关推荐

  1. python画父子关系图_将有父子关系的一维数组转换成树形结构(多维)数据

    先来个函数注释 : /** * 将有父子关系的一维数组转换成树形结构(多维)数据 * console.log(JSON.stringify(setTreeData(data), null, 2)); ...

  2. mysql 父子维,将有父子关系的一维数组转换成树形结构(多维)数据

    拉莫斯之舞 先来个函数注释 :/** * 将有父子关系的一维数组转换成树形结构(多维)数据 * console.log(JSON.stringify(setTreeData(data), null,  ...

  3. mysql 表名批量转大写_(转)mysql数据库表名批量修改大小写

    由于不用服务器对mysql的表名的大小写敏感要求不一致,经常在出现线上的数据库down到了本地不能运行的情况,贴出一段代码用来批量修改数据库表名大小写. DELIMITER // DROP PROCE ...

  4. java递归查询无限极分类_sqlserver实现树形结构递归查询(无限极分类)的方法

    SQL Server 2005开始,我们可以直接通过CTE来支持递归查询,CTE即公用表表达式 百度百科 公用表表达式(CTE),是一个在查询中定义的临时命名结果集将在from子句中使用它.每个CTE ...

  5. java 流程引擎_java工作流引擎Jflow父子流程demo

    关键字 驰骋工作流引擎 流程快速开发平台 workflow ccflow jflow  .net开源工作流 2.定义 一个流程A的一个节点,因工作的需要调起另外的流程B,A就叫父流程,B就叫子流程.如 ...

  6. java前台构建_Java编程第43讲——实现前端后一体的Web服务器

    随着Web前端技术的迅猛发展,现在的Web开发已经明显分为两大阵营:Web前端和Web后端,接着UI设计又从Web前端分离出去,成为专门的团队.当我们从JavaScript开始,一路经过jQuery. ...

  7. java联接pg库_成为Java流大师–第5部分:将联接的数据库表转换为流

    java联接pg库 是否可以将联接的数据库表转换为Java Stream? 答案是肯定的. 由于我们已经多次提出这个问题,因此我们决定写另一篇动手实验文章,说明如何执行更高级的Stream Joins ...

  8. 成为Java流大师–第5部分:将联接的数据库表转换为流

    是否可以将联接的数据库表转换为Java Stream? 答案是肯定的. 既然我们已经多次提出这个问题,我们决定写另一篇动手实验文章,解释如何执行更高级的Stream Joins. 因此,这里是第六篇中 ...

  9. java实体类生成mysql表_springboot+mybatis通过实体类自动生成数据库表的方法

    前言 本章介绍使用mybatis结合mysql数据库自动根据实体类生成相关的数据库表. 首先引入相关的pom包我这里使用的是springboot2.1.8.RELEASE的版本 org.mybatis ...

最新文章

  1. Nature:AI为什么总是歧视重重?
  2. linux导出并追加到文件,linux – 如何将awk结果输出到文件
  3. UIWebView相关应用
  4. python Gunicorn
  5. IL应用之——用IL分析接口的本质
  6. LeetCode 5377. 将二进制表示减到 1 的步骤数
  7. linux下sqlserver端口号,linux下连接sqlserver配置及otl编程.docx
  8. java使用RSA加密方式,实现数字签名
  9. ipv4网络配置方法
  10. Atitit 泛型原理与理解attilax总结
  11. 《惢客创业日记》2021.02.12(周五)月老的新口号
  12. 解决LaTeX中的\pdfendlink ended up in different nesting level than \pdfstartlink.问题
  13. Active/Active与Active/Passive
  14. CreateCompatibleDC(HDC hdc);
  15. ubuntu12.04 rythonbox不支持mms电台
  16. Druid配置好之后sql监控界面不显示sql语句的可能原因
  17. 工业互联 智造未来 “2018 智造中国峰会•上海松江” 在上海市松江区隆重召开
  18. python+vue+elementui大学生网络教学平台
  19. CentOS 端口转发
  20. 怎么把模糊的照片变清晰?这篇文章告诉你

热门文章

  1. HDU 3916 Sequence Decomposition 【贪心】
  2. codeforce 457DIV2 C题
  3. 手机界面常见的的九宫格
  4. C++编译报错:重复定义
  5. PKM(个人知识管理)类软件收集(偶尔更新列表)
  6. 写一个Android输入法01——最简步骤
  7. Sql Server 关于整表插入另一个表部分列的语法以及select 语句直接插入临时表的语法 (转帖)...
  8. C语言实现简单的电子通讯录2
  9. C#常用单元测试框架比较:XUnit、NUnit和Visual Studio(MSTest)
  10. 技术分享连载(六十一)