递归、嵌套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 ...
随机推荐
- Java知多少(47)多重catch语句的使用
某些情况,由单个代码段可能引起多个异常.处理这种情况,你可以定义两个或更多的catch子句,每个子句捕获一种类型的异常.当异常被引发时,每一个catch子句被依次检查,第一个匹配异常类型的子句执行.当 ...
- USB学习笔记连载(二十一):CY7C68013A进行数据传输(一)
官方手册中给出了bulkloop参考例程,此例程是PC从端口2发送出数据,然后从端口6接收到数据,那么根据这个思想,可以进行修改,使得PC机接收到的数据不是从EP2发送过来的,而是从外部逻辑,比如FP ...
- PHP文件解密服务,微擎微赞模块解密,微擎模块解密
支持Zend/PHP5.3, Zend/PHP5.4, Zend/PHP5.5, Zend/PHP5.6解密 支持IonCube8, IonCube9, IonCube10解密 支持魔方一代,魔方二代 ...
- SpringBoot Logback配置,SpringBoot日志配置
SpringBoot Logback配置,SpringBoot日志配置 SpringBoot springProfile属性配置 ================================ © ...
- [Linux] 设置系统时区
1. 检查当前时区 以 root 身份登录. # date Fri Sep :: UTC 其中 UTC 是指当前使用的时间系统为世界标准时间,也称世界协调时间.英文名称为 Coordinated Un ...
- Kafka ACL使用实战
自0.9.0.0.版本引入Security之后,Kafka一直在完善security的功能.当前Kafka security主要包含3大功能:认证(authentication).信道加密(encry ...
- VS2017 配置ImageMagick
以下配置仅供参考,我配置完了怎样都用不了... 直接下载源码使用VS进行编译. 源码下载地址:http://imagemagick.org/script/install-source.php#wind ...
- UITableView 显示在statusbar 下面
IOS 6 升到 IOS7 之后出现的状况 新建一个工程,删除默认的ViewController,拖拽一个TableViewController到storyboard. 即使没有勾选 "Ex ...
- (转)使用 CJSON 在C语言中进行 JSON 的创建和解析的实例讲解
使用 CJSON 在C语言中进行 JSON 的创建和解析的实例讲解 本文用代码简单介绍cjson的使用方法,1)创建json,从json中获取数据.2)创建json数组和解析json数组 1. 创 ...
- MySql 远程连接的条件
1.首先看服务器防火墙 引用:http://www.cnblogs.com/silent2012/archive/2015/07/28/4682770.html CentOS 7.0默认使用的是fir ...