树形结构数据存储方案的选择和java list转tree
树形结构数据存储方案
Adjacency List:每一条记录存parent_id
Path Enumerations:每一条记录存整个tree path经过的node枚举
Nested Sets:每一条记录存 nleft 和 nright
Closure Table:维护一个表,所有的tree path作为记录进行保存。
各种方法的常用操作代价见下图


邻接表再程序中的使用:直接查询所有,然后构建树形结构数据。有序数据构建树,层级之间是有序的。可通过sql查询排序。
java list转tree
TreeNode接口
package klg.common.tree; import java.io.Serializable;
import java.util.List;
/**
*
* @author klguang
*
* @param <ID>
*/
public interface TreeNode<ID extends Serializable> { public ID getId();
public ID getParentId(); public <T extends TreeNode<ID>> void setChildren(List<T> children); }
TreeHelper工具类
package klg.common.tree; import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
/**
*
* @author klguang
*
*/
public class TreeHelper { /**
*
* @param parentID
* null 为根节点
* @param nodeList
* @param sort
* @return
*/
public static <ID extends Serializable,T extends TreeNode<ID>> List<T> buildTree(ID parentID, List<T> nodeList) {
// 根节点列表
List<T> list = new ArrayList<>();
// 顺序遍历节点列表,如果之前是有序的,那么构建树后同层级之间有序
for (int i=0; i<nodeList.size(); i++) {
T node = nodeList.get(i);
//递归入口, String.valueOf防止null值
if (String.valueOf(node.getParentId()).equals(String.valueOf(parentID))) {
// parentID作为入口
List<T> children = buildTree(node.getId(), nodeList);
node.setChildren(children);
list.add(node);
}
} return list;
}
}
案例easyui tree
package klg.common.tree; import java.io.Serializable;
import java.util.ArrayList;
import java.util.List; import javax.persistence.Access;
import javax.persistence.AccessType;
import javax.persistence.Column;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.MappedSuperclass;
import javax.persistence.Transient; /**
*
* @author klguang
*
*/
@MappedSuperclass
@Access(AccessType.FIELD)
public abstract class EasyUITreeNode<ID extends Serializable> implements Serializable, TreeNode<ID> { private static final long serialVersionUID = 850845227481354764L; @Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private ID id; @Column(name = "parent_id")
private ID parentId; @Column(name = "name", nullable = false)
private String name; @Column(name = "icon_cls")
private String iconCls; @Column(name = "state")
private String state; @Column(name = "order_num")
private Integer orderNum; @SuppressWarnings("rawtypes")
@Transient
List children = new ArrayList<>(); /**
* easyui treegrid 需求格式
*
* @return
*/
public String getText() {
return this.name;
} public ID getId() {
return id;
} public void setId(ID id) {
this.id = id;
} public ID getParentId() {
return parentId;
} public void setParentId(ID parentId) {
this.parentId = parentId;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public String getIconCls() {
return iconCls;
} public void setIconCls(String iconCls) {
this.iconCls = iconCls;
} public String getState() {
return state;
} public void setState(String state) {
this.state = state;
} public Integer getOrderNum() {
return orderNum;
} public void setOrderNum(Integer orderNum) {
this.orderNum = orderNum;
} @SuppressWarnings("unchecked")
public <T extends TreeNode<ID>> List<T> getChildren() {
return children;
} public<T extends TreeNode<ID>> void setChildren(List<T> children) {
this.children = children;
} }
使用方法
easyui tree实现类
public class Permission extends EasyUITreeNode<Long> {
//fields
}
构建树
public List<Permission> findAll(){
Sort sort = new Sort(Direction.ASC,"orderNum");
List<Permission> listData=permissionService.findList(sort);
return TreeHelper.<Long,Permission>buildTree(null, listData);
}
树形结构数据存储方案的选择和java list转tree的更多相关文章
- 【MySQL疑难杂症】如何将树形结构存储在数据库中(方案一、Adjacency List)
今天来看看一个比较头疼的问题,如何在数据库中存储树形结构呢? 像mysql这样的关系型数据库,比较适合存储一些类似表格的扁平化数据,但是遇到像树形结构这样有深度的人,就很难驾驭了. 举个栗子:现在有一 ...
- 【java基础 5】树形结构数据加载的思考
前面两篇文章,分别介绍了使用递归和非递归算法加载树形结构数据的方式,本篇文章,则是自己闲下来的时候,进行的一点小思考. 一.什么地方会用到树形结构 刚开始一看到这种结构的时候,最先是想到了家谱.家谱就 ...
- Hadoop小文件存储方案
原文地址:https://www.cnblogs.com/ballwql/p/8944025.html HDFS总体架构 在介绍文件存储方案之前,我觉得有必要先介绍下关于HDFS存储架构方面的一些知识 ...
- Github 29K Star的开源对象存储方案——Minio入门宝典
对象存储不是什么新技术了,但是从来都没有被替代掉.为什么?在这个大数据发展迅速地时代,数据已经不单单是简单的文本数据了,每天有大量的图片,视频数据产生,在短视频火爆的今天,这个数量还在增加.有数据表明 ...
- Redis百亿级Key存储方案(转)
1 需求背景 该应用场景为DMP缓存存储需求,DMP需要管理非常多的第三方id数据,其中包括各媒体cookie与自身cookie(以下统称supperid)的mapping关系,还包括了supperi ...
- MongoDb gridfs-ngnix文件存储方案
在各类系统应用服务端开发中,我们经常会遇到文件存储的问题. 常见的磁盘文件系统,DBMS传统文件流存储.今天我们看一下基于NoSQL数据库MongoDb的存储方案.笔者环境 以CentOS ...
- MySQL 5.7:非结构化数据存储的新选择
本文转载自:http://www.innomysql.net/article/23959.html (只作转载, 不代表本站和博主同意文中观点或证实文中信息) 工作10余年,没有一个版本能像MySQL ...
- Redis百亿级Key存储方案
1 需求背景 该应用场景为DMP缓存存储需求,DMP需要管理非常多的第三方id数据,其中包括各媒体cookie与自身cookie(以下统称supperid)的mapping关系,还包括了supperi ...
- 【Tree 3】树形结构数据加载的思考
前面两篇文章,分别介绍了使用递归和非递归算法加载树形结构数据的方式,本篇文章,则是自己闲下来的时候,进行的一点小思考. 一.什么地方会用到树形结构 刚开始一看到这种结构的时候,最先是想到了家谱.家谱就 ...
随机推荐
- Objective-C函数重载规则
是按照函数标签是否重复来判断是否为一个重载函数的.
- How to create PDF files in a Python/Django application using ReportLab
https://assist-software.net/blog/how-create-pdf-files-python-django-application-using-reportlab CONT ...
- lzma解压
这个软件的使用方法有点特殊:需要将要压缩为lzma格式的文件拖放到批处理上面,会自动进行处理.压缩和解压同样是拖放到上面,程序会自动处理.程序默认使用2个CPU线程进行处理,会自动判断你是压缩还是解压 ...
- MySQL 5.7.16 zip包配置
截止2016/10/16 最新版本Mysql为5.7.16,之前写过一篇APMW搭建的文章(传送门:http://www.cnblogs.com/airoot/p/4131906.html)里面介绍的 ...
- Python教程:[43]Word基本操作
使用python操作Word用到了win32com模块,我们现在就要介绍一下python对Word的基本操作,文章涉及到如何与Word程序建立连接.如果与Word文档建立连接的,以及对Word文档的基 ...
- 一款jquery和css3实现的卡通人物动画特效
之前为大家分享了很多jquery和css3的动画实例.今天给大家带来一款非常炫的jquery和css3实现的卡通人物动画特效.效果图如下: 在线预览 源码下载 实现的代码. html代码: < ...
- 基于jQuery的时间轴鼠标悬停动画插件
之前为大家分享了很多jquery插件,这次我们要来分享一款不太常见的jQuery插件,它是一个时间轴,时间轴上的每一个点在鼠标滑过时都可以显示该点的描述信息,并且鼠标滑过时都可以产生一定的动画特效,比 ...
- imx6 socketcan 发送问题
参考cansend 的方法进行发送can 数据. cansend 的生成,请查考:http://www.cnblogs.com/chenfulin5/p/6797756.html cansend 代码 ...
- 手把手教你利用微软的Bot Framework,LUIS,QnA Maker做一个简单的对话机器人
最近由于要参加微软亚洲研究院的夏令营,需要利用微软的服务搭建一个对话Bot,以便对俱乐部的情况进行介绍,所以现学了几天,搭建了一个简单的对话Bot,期间参考了大量的资料,尤其是下面的这篇博客: htt ...
- 关于Unity中的摄像机
摄像机是挂载Camera组件的能把3D世界物体拍摄成2D画面显示到屏幕上面的节点,角度不一样,位置不一样,拍摄出来的东西就不一样. Clear Flags:没有物体的时候,摄像机拍摄出的屏幕要绘制什么 ...