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

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

编程模型

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

北京市:市辖区 县

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

县:密云县 延庆县

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/459783.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[转]用Whois获得电信运营商的IP地址是如何分配的?

[转]用Whois获得电信运营商的IP地址是如何分配的? Linux下获得一些中国电信运营商的IP地址分配情况: APNIC是管理亚太地区IP地址分配的机构,它有着丰富准确的IP地址分配库,同时这些信息也是对外公开的,并提供了一个查询工具,下面…

BZOJ 2301 Problem b(莫比乌斯反演+分块优化)

题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id37166 题意:对于给出的n个询问,每次求有多少个数对(x,y),满足a≤x≤b,c≤y≤d,且gcd(x,y) k,gcd(x,y)函数为x和y的最大…

java importgeopoint_如何在地图上显示更多点(GeoPoint)?

目前,我能够在代码中显示第一个点(pointStatie)的一点,但我希望显示两个点。我想要显示我所在的位置,以及我从另一个班级通过坐标的另一点。我目前的代码是:package aexp.elistcbox;import android.os.Bundle;import android.prov…

Java实现串口通信的小样例

用Java实现串口通信(windows系统下),须要用到sun提供的串口包 javacomm20-win32.zip。当中要用到三个文件,配置例如以下: 1.comm.jar放置到 JAVA_HOME/jre/lib/ext; 2.win32com.dll放置到 JAVA_HOME/bin; 3.javax.comm…

庆祝教师节,李宁老师课程优惠劵疯抢中、会员卡优惠中,先到先得

李宁老师会员卡(9-10至9-14)大优惠:http://edu.51cto.com/member/id-12_1.html优惠劵只能购买李宁老师的视频课程:http://edu.51cto.com/member/id-12_1.html 优惠劵有效期:2015-9-10 至 2015-9-14 购买规则&#xf…

java mset_Java 反射机制(包括组成、结构、示例说明等内容)

第1部分 Java 反射机制介绍Java 反射机制。通俗来讲呢,就是在运行状态中,我们可以根据“类的部分已经的信息”来还原“类的全部的信息”。这里“类的部分已经的信息”,可以是“类名”或“类的对象”等信息。“类的全部信息”就是指“类的属性…

XML序列化和反序列化 以及相关类的写法

类的写法: 省网办数据对接中运用到 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Xml.Serialization;namespace SWBExchange.Common.Entities {public class Body{[XmlElement(ElementName "BasicIn…

python-main

当你打开一个.py文件时,经常会在代码的最下面看到if __name__ __main__:,现在就来介 绍一下它的作用.模块是对象,并且所有的模块都有一个内置属性 __name__。一个模块的 __name__ 的值取决于您如何应用模块。如果 import 一个模块,那么模块__name__ 的值…

自己动手,实现一种类似ListT的数据结构(二)

前言&#xff1a; 首先&#xff0c;小匹夫要祝各位看官圣诞快乐&#xff0c;新年愉快&#xff5e;。上一篇文章《自己动手&#xff0c;实现一种类似List<T>的数据结构(一&#xff09;》 介绍了一下不依靠List<T>实现的各种接口&#xff0c;仿造一个轻量级数据结构的…

java spring jdbc_Spring与JDBC支持

JDBC是一种标准Java编程接口(JAVA API)&#xff0c;可以将Java编程语言与广泛数据库进行连接。JDBC API库包含下面提到的每个任务&#xff0c;都是与数据库相关的常用用法。数据库的连接创建sql语句执行或提交sql语句查看或修改查询到的记录从根本上说&#xff0c;JDBC是一种规…

局域网内连接MySQL

2019独角兽企业重金招聘Python工程师标准>>> 局域网内连接MySQL 博客分类&#xff1a; MySQL MySQL局域网连接grant 我们都知道连接MySQL一般用的语句就是 jdbc:mysql://localhost:3306/database&#xff0c; 但是当你要连接到其他机器上的mysql的时候&#xff0c;…

java打印的globa类l_Spring异常集中处理和日志集中打印

使用ControllerAdvice和ExceptionHandler处理Controller层的异常&#xff1a;ControllerAdvicepublic class GlobalExceptionHandler {private static final Logger LOGGER LoggerFactory.getLogger(GlobalExceptionHandler.class);/*** 处理所有不可知的异常* param e* retur…

[leetcod] Clone Graph

题目&#xff1a; Clone an undirected graph. Each node in the graph contains a label and a list of its neighbors. OJs undirected graph serialization: Nodes are labeled uniquely. We use # as a separator for each node, and , as a separator for node label and …

【iOS7一些总结】9、与列表显示(在):列表显示UITableView

列表显示&#xff0c;顾名思义它是在一个列表视图的形式显示在屏幕上的数据的内容。于ios在列表视图UITableView达到。这个类在实际应用中频繁&#xff0c;是很easy理解。这里将UITableView的主要使用方法总结一下以备查。UITableView定义在头文件UITableView.h中&#xff0c;详…

java聊天软件课程设计_[计算机课程设计] JAVA课程设计-聊天室

本系统基于C/S模式。新的时代,新的世纪,在当今这个发达的信息时代,网上办公,极为普遍,生活变的简单化,人们在家就可以办公,是信息化时代的标志.我经过多方的调查和研究,并灵活运用了自己所学的知识,编写了这个非常适用的一个小软件.它是通过RMI通信协议,利用JAVA的多线程技术,将…

iOS 获取手机信息

待续&#xff1b;转载于:https://www.cnblogs.com/xieyier/p/4194271.html

show status和show variables区别解析

1.show status 查看系统运行的实时状态&#xff0c;便于dba查看mysql当前运行的状态&#xff0c;做出相应优化&#xff0c;动态的&#xff0c;不可认为修改&#xff0c;只能系统自动update。MariaDB [(none)]> show status like %conn%;--------------------------------…

【Javascript 拾遗之三】Closure 闭包

说起闭包这个概念&#xff0c;其实是离散数学中的一种定义&#xff0c;而很程序员们耳熟能详但不一定能说清楚它的含义和用途。本文先简单地介绍下离散数学中的闭包&#xff0c;然后再探讨一下Javascript语言中的闭包是如何创建和应用的。 Closure 闭包 1、闭包的定义 -离散数学…

java递归空瓶换饮料_问题描述:一次买n瓶可乐,k个空瓶可以换一瓶饮料,那么一共能喝多少瓶饮料? | 学步园...

/***问题描述&#xff1a;一次买n瓶可乐&#xff0c;k个空瓶可以换一瓶饮料&#xff0c;那么一共能喝多少瓶饮料&#xff1f;*下面用不同的方法实现了这个问题(Java实现)&#xff1a;*1.递归方法*2.非递归方法*3.公式法*/public class CocaCola{public int Count(int n, int k)…

SpringMVC(一):环境搭建

2019独角兽企业重金招聘Python工程师标准>>> //TODO 转载于:https://my.oschina.net/u/1020238/blog/505272