最近做关于文档空间的东西,主要的问题就是目录树的问题,以及查询性能的问题。
目录树主要采用parentId的方式来标识父节点,根据网上关于树结构的分析,几种方式各有优劣,无外乎都是根据不同的场景。如果对于查询比较多的业务场景则采用这种方式的效率更高一点,频繁的CURD 可以采用左右孩子节点的方式,省去了递归,下面是关于目录树的完整实现过程,如果有问题,欢迎小伙伴评论区留言!
DROP TABLE IF EXISTS `menu`;
CREATE TABLE `menu` (
`id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT 'ID',
`name` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '节点名',
`parent_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '父节点ID',
`type` int(0) NOT NULL COMMENT '0:目录节点 1:文档',
`create_time` datetime(0) NOT NULL COMMENT '创建时间',
`update_time` datetime(0) NOT NULL COMMENT '创建时间',
`space` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '文档空间',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
@Entity
@Data
@Table(name = "menu")
public class Menu {
@Id
@Column(name = "id")
private String id;
@Column(name = "name")
private String name;
@Column(name = "parent_id")
private String parentId;
@Column(name = "type")
private String type;
@Column(name = "create_time")
private Date createTime;
@Column(name = "update_time")
private Date updateTime;
@Column(name = "space")
private String space;
}
public class TreeUtil {
public static Map<String, Object> mapArray = new LinkedHashMap<String, Object>();
public List<NodeDTO> nodeDTOs;
public List<Object> list = new ArrayList<>();
public List<Object> treeMenu(List<NodeDTO> node) {
this.nodeDTOs = node;
for (NodeDTO nodeDTO : node) {
Map<String, Object> mapArr = new LinkedHashMap<String, Object>();
if (nodeDTO.getParentId().equals("-1")) {
setTreeMap(mapArr, nodeDTO);
list.add(mapArr);
}
}
return list;
}
/**
* 构建孩子节点
*
* @param id
* @return
*/
public List<?> menuChild(String id) {
List<Object> lists = new ArrayList<Object>();
for (NodeDTO a : nodeDTOs) {
Map<String, Object> childArray = new LinkedHashMap<String, Object>();
if (a.getParentId().equals(id)) {
setTreeMap(childArray, a);
lists.add(childArray);
}
}
return lists;
}
/**
* 构建树节点信息
*
* @param mapArr
* @param nodeDTO
*/
private void setTreeMap(Map<String, Object> mapArr, NodeDTO nodeDTO) {
if (nodeDTO.getType().equals("0")) {
mapArr.put("key", nodeDTO.getId());
mapArr.put("id", nodeDTO.getId());
mapArr.put("name", nodeDTO.getName());
mapArr.put("parentId", nodeDTO.getParentId());
mapArr.put("type", "目录");
mapArr.put("children", menuChild(nodeDTO.getId()));
} else {
mapArr.put("key", nodeDTO.getId());
mapArr.put("id", nodeDTO.getId());
mapArr.put("title", nodeDTO.getName());
mapArr.put("parentId", nodeDTO.getParentId());
mapArr.put("type", "文档");
}
}
@Data
public class NodeDTO {
private String id;
private String name;
private String parentId;
private String type;
private String space;
public NodeDTO(String id, String name, String parentId, String type, String space) {
this.id = id;
this.name = name;
this.parentId = parentId;
this.type = type;
this.space = space;
}
}
以上是关于生成树结构信息的所需要的代码,具体现在的问题就是,从数据库中查出一条条信息,然后生产json格式的树信息,下面的代码完成了整合生产的过程:
1.数据库查询出的信息是List形式的集合。集合的实体是上面的封装节点,List;
2.使用工具类生成List集合的树信息
TreeUtil treeUtil = new TreeUtil();
List<Object> objects = treeUtil.treeMenu(menus);
3.转换为json格式返回,使用alibaba的工具类:JSON.toJSON(objects)
OK!