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

比如我们需要编写一个树形结构的菜单,那么我们可以使用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. numpy的介绍——总览

    为什么有numpy这个库呢? 1. 准安装的Python中用列表(list)保存一组值,可以用来当作数组使用,不过由于列表的元素可以是任何对象,因此列表中所保存的是对象的指针.这样为了保存一个简单的[ ...

  2. 【Math】根据置信度、样本数相关推导过程

    时间长了会忘,备忘下. http://blog.csdn.net/liangzuojiayi/article/details/78044780 http://wiki.mbalib.com/wiki/ ...

  3. traff.sh

    #!/bin/bash #网络监控 while [ "1" ] do eth=$1 RXpre=$(cat /proc/net/dev | grep $eth | tr : &qu ...

  4. 三剑客之grep

    简介 grep (global search regular expression(RE) and print out the line,全面搜索正则表达式并把行打印出来)是一种强大的文本搜索工具,它 ...

  5. 前端基础开发之HTML

    简介:                                                                                1.HTML是什么? htyper ...

  6. Db2性能:系统CPU高问题分析的一些思路

    Db2性能:系统CPU高问题分析的一些思路 1. 如何判断CPU高? 有很多操作系统的命令可以看出来,比如ps -elf,iostat, vmstat, top/topas, 2. 收集数据 CPU高 ...

  7. [No0000138]软件开发基础知识

    1. 本文目的 本文目的在于,介绍软件开发的各种基础知识 以实现,看了之后,对于软件开发的很多领域的基础知识有所了解 如此在进行后续的真正的软件开发时,遇到各种细节知识,才会明白由来和背景知识 第 1 ...

  8. Android Studio自动排版的两种方法

    Android Studio这样的集成开发环境虽然代码自动化程度很高,但是自动化程度高导致人的自主性就下降了,而且总是依赖编辑器的功能也会搞得代码排版很别扭. 最难受的是你在Android Studi ...

  9. [development][dpdk][hugepage] 为不同的结点分配不同大小的大页内存

    这个事来自dpdk, 所以, 先参考. http://dpdk.org/doc/guides/linux_gsg/sys_reqs.html 当前, 假设你已经读过上边内容, 知道大页内存时候, dp ...

  10. Flink – metrics V1.2

    WebRuntimeMonitor   .GET("/jobs/:jobid/vertices/:vertexid/metrics", handler(new JobVertexM ...