递归、嵌套for循环、map集合方式实现树形结构菜单列表查询
有时候, 我们需要用到菜单列表,但是怎么样去实现一个菜单列表的编写呢,这是一重要的问题。
比如我们需要编写一个树形结构的菜单,那么我们可以使用JQuery的zTree插件:http://www.treejs.cn/v3/main.php#_zTreeInfo

例如现在需要编写一个这样的菜单列表。那么就可以使用JQuery的zTree插件。
先看一下数据库表结构。
CREATE TABLE `permission` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
`pid` int(11) DEFAULT NULL,
`url` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;

1、前端页面。
<div class="panel-body">
<ul id="permissionTree" class="ztree"></ul>
</div>
<script>
$(function () { var setting = {
async: {
enable: true,
url:"${APP_PATH}/permission/loadData",
autoParam:["id", "name=n", "level=lv"],
otherParam:{"otherParam":"zTreeAsyncTest"},
} }; //树形结构
$.fn.zTree.init($("#permissionTree"), setting);
});
</script>
2、在这里呢,我使用的是ssm框架。所以就提交到controller层来进行操作。
Permission类的代码
import java.util.ArrayList;
import java.util.List; public class Permission { private Integer id;
private String name;
private String url;
private Integer pid;
private boolean open = true;
private boolean checked = false;
private String icon;
private List<Permission> children = new ArrayList<Permission>(); public boolean isChecked() {
return checked;
}
public void setChecked(boolean checked) {
this.checked = checked;
}
public String getIcon() {
return icon;
}
public void setIcon(String icon) {
this.icon = icon;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public Integer getPid() {
return pid;
}
public void setPid(Integer pid) {
this.pid = pid;
}
public boolean isOpen() {
return open;
}
public void setOpen(boolean open) {
this.open = open;
}
public List<Permission> getChildren() {
return children;
}
public void setChildren(List<Permission> children) {
this.children = children;
} }
使用controller这里我使用三种方式来进行查找 。
(1)递归方式读取各节点
controller层
/**
* 异步加载树结点
* @return
*/
@RequestMapping("/loadData")
@ResponseBody
public List<Permission> loadData(){
// 递归查询数据
Permission parent = new Permission();
parent.setId(0);
queryChildPermissions(parent);
return parent.getChildren();
}
/**
* 递归查询许可信息
* 1) 方法自己调用自己
* 2)方法一定要存在跳出逻辑
* 3)方法调用时,参数之间应该有规律
* 4) 递归算法,效率比较低
* @param parent
*/
private void queryChildPermissions(Permission parent){
List<Permission> childPermissions = permissionService.queryChildPermissions(parent.getId());
for (Permission permission :childPermissions) {
queryChildPermissions(permission);
}
parent.setChildren(childPermissions);
}
service层
public Permission queryRootPermission() {
return permissionMapper.queryRootPermission();
}
mappern层
@Select("select * from permission where pid is null")
Permission queryRootPermission();
(2)嵌套for循环方式读取各节点
controller层
/**
* 异步加载树结点
* @return
*/
@RequestMapping("/loadData")
@ResponseBody
public List<Permission> loadData(){
List<Permission> permissions=new ArrayList<Permission>();
// 查询所有的许可数据
List<Permission> ps = permissionService.queryAll();
for ( Permission p : ps ) {
// 子节点
Permission child = p;
if ( p.getPid() == 0 ) {
permissions.add(p);
} else {
for ( Permission innerPermission : ps ) {
if ( child.getPid().equals(innerPermission.getId()) ) {
// 父节点
Permission parent = innerPermission;
// 组合父子节点的关系
parent.getChildren().add(child);
break;
}
}
}
} return permissions;
}
service层
public List<Permission> queryAll() {
return permissionMapper.queryAll();
}
mapper层
@Select("select * from permission")
List<Permission> queryAll();
(3)map集合方式读取各节点
controller层
/**
* 异步加载树结点
* @return
*/
@RequestMapping("/loadData")
@ResponseBody
public List<Permission> loadData(){
List<Permission> permissions=new ArrayList<Permission>(); // 查询所有的许可数据
List<Permission> ps = permissionService.queryAll(); Map<Integer, Permission> permissionMap = new HashMap<Integer, Permission>();
for (Permission p : ps) {
permissionMap.put(p.getId(), p);
}
for ( Permission p : ps ) {
Permission child = p;
if ( child.getPid() == 0 ) {
permissions.add(p);
} else {
Permission parent = permissionMap.get(child.getPid());
parent.getChildren().add(child);
}
}
return permissions;
}
service层
public List<Permission> queryAll() {
return permissionMapper.queryAll();
}
mapper层
@Select("select * from permission")
List<Permission> queryAll();
三种方法的总结 :
使用递归会使数据库查询非常频繁,不能进行性能优化
使用嵌套for循环没有使用索引,不够快速
使用map集合就使用了索引,加快查询速度。
递归、嵌套for循环、map集合方式实现树形结构菜单列表查询的更多相关文章
- js前台取用后台传递过来的map集合方式
在处理有些特殊需求的时候,我们需要在前台页面的js中获取后台传递过来的map集合类型的参数,并且进行调用,代码如下: 在后台我们拼装出如下的集合: Map<String,Grade> gr ...
- mybatis框架,使用foreach实现复杂结果的查询--循环List集合方式
需求,根据用户角色列表 查询用户列表信息 之前我们传入的参数是Array,一个数组的形式,现在我们传入的是一个List集合,其他条件没有变化. /** * 需求:传入指定的用户角色,用户角色有1-n ...
- Day11_55_在Map集合中使用泛型
在Map集合中使用泛型 ``` import java.util.HashMap; import java.util.Iterator; import java.util.Map; import ja ...
- Map集合遍历的四种方式理解和简单使用-----不能for循环遍历
Map集合遍历的四种方式理解和简单使用 ~Map集合是键值对形式存储值的,所以遍历Map集合无非就是获取键和值,根据实际需求,进行获取键和值 1:无非就是通过map.keySet()获取到值,然后 ...
- Map集合循环遍历的几种方式
package cn.jdbc.test;import java.util.HashMap;import java.util.Iterator;import java.util.Map;import ...
- Map集合的两种遍历方式
Map集合:即 接口Map<K,V> map集合的两种取出方式: 1.Set<k> keyset: 将map中所有的键存入到set集合(即将所有的key值存入到set中) ...
- 遍历Map集合:java.util.Map.Entry、KeySet两种方式
遍历Map集合的两种方式: 1.用KeySet Map.keySet(),返回一个存放所有key的set集合,通过遍历集合,根据key值取出所有的value值. Map<String,Strin ...
- Map集合遍历的四种方式理解和简单使用
~Map集合是键值对形式存储值的,所以遍历Map集合无非就是获取键和值,根据实际需求,进行获取键和值 1:无非就是通过map.keySet()获取到值,然后根据键获取到值 for(String s:m ...
- Map集合的两种取出方式
Map集合有两种取出方式, 1.keySet:将Map中的键存入Set集合,利用set的迭代器来处理所有的键 举例代码如下: import java.util.*; class Test { publ ...
随机推荐
- /proc详解
内容摘要:Linux系统上的/proc目录是一种文件系统,即proc文件系统. Linux系统上的/proc目录是一种文件系统,即proc文件系统.与其它常见的文件系统不同的是,/proc是一种伪文件 ...
- svn-checkout后,循环遍历查找包含某字符串的文件
这里涉及几个知识点: 1.安装subversion,不多说了,网上有教程 2.循环遍历所有目录层级,找相 关文件 #!/bin/bash #########svn checkout项目出来 svn_d ...
- Mysql系列八:Mycat和Sharding-jdbc的区别、Mycat分片join、Mycat分页中的坑、Mycat注解、Catlet使用
一.Mycat和Sharding-jdbc的区别 1)mycat是一个中间件的第三方应用,sharding-jdbc是一个jar包 2)使用mycat时不需要改代码,而使用sharding-jdbc时 ...
- ELK+Filebeat+Kafka+ZooKeeper 构建海量日志分析平台
日志分析平台,架构图如下: 架构解读 : (整个架构从左到右,总共分为5层) 第一层.数据采集层 最左边的是业务服务器集群,上面安装了filebeat做日志采集,同时把采集的日志分别发送给两个logs ...
- portfolio
1.工作量计算逻辑: 原始待办事项: 预估2个冲刺,如下图所示: Sprint1的故事点计划工作量5,空闲工作量28.如下图 Sprint2为预估冲刺,指的是预估待办事项在后续冲刺的预估计划,后续冲刺 ...
- highCharts图表入门简介
一.Highcharts简介 Highcharts:功能强大.开源.美观.图表丰富.兼容绝大多数浏览器的纯js图表库 Highcharts是一款纯javascript编写的图表库,能够很简单便捷的在W ...
- IOC容器特性注入第六篇:利用MVC注入点,把容器启动
这里是利用MVC三个注入点中的:IDependencyResolver 进行注入 在全局类中Global.asax代码如下: #region MVC Inject System.Web.Mvc.Dep ...
- windows下特殊字符无法用来命名
原则上可以利用键盘输入的英文字母.符号.空格.中文等均可以作为合法字符,但由于以下字符由系统保留它用,因此不能用在文件命名中: : / \ ? * “ < > | 注: ...
- mem 0908
taglib http://blog.csdn.net/zyujie/article/details/8735730 dozer: Dozer可以在JavaBean到JavaBean之间进行递归数据复 ...
- Tetrahedron based light probe interpolation(基于四面体的Light Probe插值)
在当前的游戏引擎中,使用Light Probe来计算全局环境光对于动态物体的影响是一种很主流的方法.在预处理阶段生成完场景的Light Probe之后,传统的方法采用查找最近的8个相邻的Probe然后 ...