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

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

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值