有时候, 我们需要用到菜单列表,但是怎么样去实现一个菜单列表的编写呢,这是一重要的问题。

比如我们需要编写一个树形结构的菜单,那么我们可以使用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集合方式实现树形结构菜单列表查询的更多相关文章

  1. js前台取用后台传递过来的map集合方式

    在处理有些特殊需求的时候,我们需要在前台页面的js中获取后台传递过来的map集合类型的参数,并且进行调用,代码如下: 在后台我们拼装出如下的集合: Map<String,Grade> gr ...

  2. mybatis框架,使用foreach实现复杂结果的查询--循环List集合方式

    需求,根据用户角色列表  查询用户列表信息 之前我们传入的参数是Array,一个数组的形式,现在我们传入的是一个List集合,其他条件没有变化. /** * 需求:传入指定的用户角色,用户角色有1-n ...

  3. Day11_55_在Map集合中使用泛型

    在Map集合中使用泛型 ``` import java.util.HashMap; import java.util.Iterator; import java.util.Map; import ja ...

  4. Map集合遍历的四种方式理解和简单使用-----不能for循环遍历

    Map集合遍历的四种方式理解和简单使用   ~Map集合是键值对形式存储值的,所以遍历Map集合无非就是获取键和值,根据实际需求,进行获取键和值 1:无非就是通过map.keySet()获取到值,然后 ...

  5. Map集合循环遍历的几种方式

    package cn.jdbc.test;import java.util.HashMap;import java.util.Iterator;import java.util.Map;import ...

  6. Map集合的两种遍历方式

    Map集合:即 接口Map<K,V> map集合的两种取出方式:    1.Set<k> keyset: 将map中所有的键存入到set集合(即将所有的key值存入到set中) ...

  7. 遍历Map集合:java.util.Map.Entry、KeySet两种方式

    遍历Map集合的两种方式: 1.用KeySet Map.keySet(),返回一个存放所有key的set集合,通过遍历集合,根据key值取出所有的value值. Map<String,Strin ...

  8. Map集合遍历的四种方式理解和简单使用

    ~Map集合是键值对形式存储值的,所以遍历Map集合无非就是获取键和值,根据实际需求,进行获取键和值 1:无非就是通过map.keySet()获取到值,然后根据键获取到值 for(String s:m ...

  9. Map集合的两种取出方式

    Map集合有两种取出方式, 1.keySet:将Map中的键存入Set集合,利用set的迭代器来处理所有的键 举例代码如下: import java.util.*; class Test { publ ...

随机推荐

  1. /proc详解

    内容摘要:Linux系统上的/proc目录是一种文件系统,即proc文件系统. Linux系统上的/proc目录是一种文件系统,即proc文件系统.与其它常见的文件系统不同的是,/proc是一种伪文件 ...

  2. svn-checkout后,循环遍历查找包含某字符串的文件

    这里涉及几个知识点: 1.安装subversion,不多说了,网上有教程 2.循环遍历所有目录层级,找相 关文件 #!/bin/bash #########svn checkout项目出来 svn_d ...

  3. Mysql系列八:Mycat和Sharding-jdbc的区别、Mycat分片join、Mycat分页中的坑、Mycat注解、Catlet使用

    一.Mycat和Sharding-jdbc的区别 1)mycat是一个中间件的第三方应用,sharding-jdbc是一个jar包 2)使用mycat时不需要改代码,而使用sharding-jdbc时 ...

  4. ELK+Filebeat+Kafka+ZooKeeper 构建海量日志分析平台

    日志分析平台,架构图如下: 架构解读 : (整个架构从左到右,总共分为5层) 第一层.数据采集层 最左边的是业务服务器集群,上面安装了filebeat做日志采集,同时把采集的日志分别发送给两个logs ...

  5. portfolio

    1.工作量计算逻辑: 原始待办事项: 预估2个冲刺,如下图所示: Sprint1的故事点计划工作量5,空闲工作量28.如下图 Sprint2为预估冲刺,指的是预估待办事项在后续冲刺的预估计划,后续冲刺 ...

  6. highCharts图表入门简介

    一.Highcharts简介 Highcharts:功能强大.开源.美观.图表丰富.兼容绝大多数浏览器的纯js图表库 Highcharts是一款纯javascript编写的图表库,能够很简单便捷的在W ...

  7. IOC容器特性注入第六篇:利用MVC注入点,把容器启动

    这里是利用MVC三个注入点中的:IDependencyResolver 进行注入 在全局类中Global.asax代码如下: #region MVC Inject System.Web.Mvc.Dep ...

  8. windows下特殊字符无法用来命名

    原则上可以利用键盘输入的英文字母.符号.空格.中文等均可以作为合法字符,但由于以下字符由系统保留它用,因此不能用在文件命名中: :   /  \  ?  *  “  <  >  |  注: ...

  9. mem 0908

    taglib http://blog.csdn.net/zyujie/article/details/8735730 dozer: Dozer可以在JavaBean到JavaBean之间进行递归数据复 ...

  10. Tetrahedron based light probe interpolation(基于四面体的Light Probe插值)

    在当前的游戏引擎中,使用Light Probe来计算全局环境光对于动态物体的影响是一种很主流的方法.在预处理阶段生成完场景的Light Probe之后,传统的方法采用查找最近的8个相邻的Probe然后 ...