在我们的开发中,很多时候在显示一个具有层级结构的下拉框,效果如下:
在数据库中的数据是通过一个parentId实现的。我在学习汤阳光同志的视频中,领略了其思想,利用递归实现了自己的层级树。
/**
* 辅助分类生成树状结构列表的工具类,名称根据层级加前缀
*/
public class Models2TreeUtil{
/**
* @Title: findAllCategories2Tree
* @Description:根据topCategory找到所有的category,形成树形结构
* @param topCategories
* @return List
*/
public static final List<Category> findAllCategories2Tree(List<Category> topCategories){
List<Category> list = new ArrayList<Category>();
walkCategoryTreeList(topCategories, "┣", list);
return list;
}
/**
* @Title: walkCategoryTreeList
* @Description:遍历分类树,把遍历出的分类信息放到指定的集合中
* @param topCategories
* @param string
* @param list
*/
private static final void walkCategoryTreeList(List<Category> topCategories, String prefix, List<Category> list){
for(Category top : topCategories){
// 顶点
/*
* Category copy = new Category(); copy.set("id", top.getInt("id"));
* copy.set("level", top.getInt("level")); copy.set("name", prefix +
* top.get("name")); list.add(copy); // 把副本添加到同一个集合中
*/
top.set("name", prefix + top.get("name"));
list.add(top);
// 子树
walkCategoryTreeList(top.getChildren(), " " + prefix, list); // 使用全角的空格
}
}
/**
* @Title: findOrgs2TreeWithLevel
* @Description:根据层数返回树形的机构
* @param topOrgs
* @param i
* @return List<Organization>
*/
public static List<Organization> findOrgs2TreeWithLevel(List<Organization> topOrgs, int level){
// 添加缓存支持
ICache cache = DbKit.getConfig(Organization.class).getCache();
String cacheName = "shiro-activeSessionCache";
String key = "orgTree";
List<Organization> result = cache.get(cacheName, key);
if(result == null){
System.out.println("用我了吗?");
result = new ArrayList<Organization>();
walkOrgTreeListWithLevel(topOrgs, "┣", result, level);
cache.put(cacheName, key, result);
}
return result;
}
/**
* // 该方法只适合数据量比较小的情况,数据量大的时候可能出现内存溢出的情况
*
* @Title: walkOrgTreeListWithLevel
* @Description:根据顶层机构返回
* @param topOrgs
* @param prefix
* @param list
*/
private static void walkOrgTreeListWithLevel(List<Organization> topOrgs, String prefix, List<Organization> list,
int level){
// 最后一层就退出
if(level == 0){
return;
}
for(Organization top : topOrgs){
Organization org = new Organization();
org.set("id", top.get("id"));
org.set("DisplayName", prefix + top.get("DisplayName"));
list.add(org);
// 子树
walkOrgTreeListWithLevel(top.getChildren(), " " + prefix, list, level - 1); // 使用全角的空格
}
}
}
更进一步的是在两个地方优化了:缓存支持,最大层级限制。
缓存支持需要在JFinal的插件中配置缓存插件,getChildren()还是按照普通的方式获取子的即可。
// ECache缓存插件配置
EhCachePlugin ehPlugin = new EhCachePlugin(
this.getClass().getResource("/").getPath().replaceFirst("/", "") + "ehcache-shiro.xml");
me.add(ehPlugin);
public List<Organization> getChildren(){
return dao.find("select * from organization o where o.parentid=?", this.getInt("id"));
}
通过一个int的level参数即可简单滴实现最大层级限制!在使用的时候都需要传入一个top列表,这个表示最上层,然后通过level控制往下的深度。当然,你在调用的时候传入第二层的,level=2,那就返回2,3这两层的数据。