我们通常会在应用中碰到树形结构的内容,比如 文件夹/文件模型, 部门组织结构,目录树等等,通常在设计模式中叫做 compose 模式。
在数据库中常常这样表示: 我们以Catalog (分级目录) 为例子
Catalog (分级目录)
字段名称
字段
类型
备注
目录ID
catalog_id
varchar(36)
pk, not null
目录名称
catalog_name
varchar(50)
not null
父目录ID
parent_id
varchar(36)
fk
创建时间
create_datetime
datetime
not null
目录描述
description
varchar(200)
我们考虑在数据库中一次将所有数据读入内存,然后在内存中生成一个Tree,这样可以减少数据库的访问,增加性能,并且只有的数据方式改变的时候,全部重新从数据库中生成Tree,否则一直保持在内存中。
我们使用标准的DAO模式先生成 POJO类(Catalog)和DAO类(CatalogDAO)。
然后我们建立相对通用的 Tree 和 TreeNode 类。
Tree.java
package
com.humpic.helper.tree;
import
java.util.
*
;
import
org.apache.commons.lang.StringUtils;
import
org.apache.commons.logging.Log;
import
org.apache.commons.logging.LogFactory;
public
abstract
class
Tree {
protected
static
Log log
=
LogFactory.getLog(Tree.
class
);
private
Map treeNodeMaps
=
new
Hashtable();
private
TreeNode root;
/**
* root if it's parent is empty
*/
protected
void
reload(List nodes) {
log.info(
"
tree will start reload all data
"
);
synchronized
(
this
) {
//
initialize
treeNodeMaps.clear();
root
=
null
;
List treeNodes
=
new
Vector(nodes.size());
for
(
int
i
=
0
; i
<
nodes.size(); i
++
) {
TreeNode node
=
this
.transform(nodes.get(i));
//
transform
treeNodes.add(node);
node.setTree(
this
);
treeNodeMaps.put(node.getNodeId(), node);
}
for
(
int
i
=
0
; i
<
treeNodes.size(); i
++
) {
TreeNode node
=
(TreeNode) treeNodes.get(i);
String parentId
=
node.getParentId();
if
(this
.
isRootNode(node)) {
if
(root
==
null
) {
root
=
node;
}
else
{
log.error(
"
find more then one root node. ignore.
"