ztree树形结构菜单_mybatis分页查询

1、二级树形菜单

效果图

表结构

业务层:

二级菜单实现思路:

1)查出父菜单(pid=0),通过遍历父菜单获得父菜单(id),根据父菜单id值作为条件查出子菜单(子菜单pid=父菜单id),接着整理父子菜单关系;这种不推荐,假如所有菜单为18个,查出父菜单3个封装到集合时需要遍历18次,根据父菜单id作为查询子菜单的条件需要遍历3*18次。

2)一次性查出所有菜单18个,使用程序进行组合,这种推荐,以空间换时间。

封装菜单实体

业务层:


public List<TPermission> getAllMenus() {

    // 保存父菜单
    List<TPermission> menus = new ArrayList<TPermission>();
    Map<Integer, TPermission> map = new HashMap<Integer, TPermission>();

    // 查询所有菜单
    // 参数为null,表示不带条件查询菜单
    List<TPermission> list = mapper.selectByExample(null);
    System.out.println("所有菜单=========>");
    System.out.println(list);

    // 1、将所有菜单都放在map中
    // 都是引用,如果从map中拿到这个数据改变以后,map中页面变化
    for (TPermission tPermission : list) {
        map.put(tPermission.getId(), tPermission);
    }

    // 2、先封装父菜单,再将子菜单放入到父菜单中
    for (TPermission tPermission : list) {
        if (tPermission.getPid() == 0) {
            menus.add(tPermission);
        } else {
            // tPermission(子菜单),拿到父菜单
            Integer pid = tPermission.getPid();
            // 拿到父菜单;以pid的值作为map中的菜单id,就是父菜单
            TPermission p_menu = map.get(pid);
            // 拿到当前父菜单的子菜单;子菜单会有一些额外的问题
            // 这个list第一次获取是没有的,如果添加上一次以后。这个list是有的
            List<TPermission> childs = p_menu.getChilds();
            if (childs != null) {
                // 当前有子菜单
                childs.add(tPermission);
            } else {
                // 当前没有子菜单
                childs = new ArrayList<>();
                // 添加当前子菜单
                childs.add(tPermission);
                // 将当前整理好的childs设置进去
                p_menu.setChilds(childs);
            }
        }
    }

    System.out.println("父菜单===========>");
    System.out.println(menus);

    return menus;
}

控制层

1)将整理好的父子菜单数据放入到session域中,当前用户的这次会话一直使用,只需要去数据库查询一次


@RequestMapping(value = "/main.html")
public String toMainPage(HttpSession session) {

    // 校验
    // 判断session中是否有这个用户,如果没有去登陆页面
    Object object = session.getAttribute(Constants.LOGIN_USER);
    if (object == null) {
        // 用户没登陆
        return "redirect:/login.jsp";
    } else {
        // 用户登陆才来到主页,session中没有菜单,或者菜单被我们从session中清除了
        if (session.getAttribute(Constants.USER_MENUS) == null) {
            // 1、查出所有菜单,在页面进行显示
            List<TPermission> menus = ps.getAllMenus();
            // 2、将查到的菜单放在session域中
            // 菜单这些数据没必要每次来到主页,都调用service方法进行查询;放在session用户,
            // 当前用户的这次会话一直使用,只需要去数据库查一次
            session.setAttribute(Constants.USER_MENUS, menus);
        }

        return "manager/main";
    }

}

前台:

1)引入:<%@ taglib prefix=”fn” uri=”http://java.sun.com/jsp/jstl/functions"%>
计算后台传过来的list集合的长度:${fn:length(p_menu.childs)}


<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%>
<div class="col-sm-3 col-md-2 sidebar">
    <div class="tree">
        <ul style="padding-left: 0px;" class="list-group">

            <li class="list-group-item tree-closed"><a href="main.html"><i
                    class="glyphicon glyphicon-dashboard"></i> 控制面板</a></li>
            <!-- 遍历父菜单 -->
            <c:forEach items="${sessionScope.userMenus}" var="p_menu">
                <li class="list-group-item tree-closed"><span><i
                        class="${p_menu.icon}"></i>${p_menu.name} <span class="badge"
                        style="float: right">${fn:length(p_menu.childs)}</span></span>
                    <ul style="margin-top: 10px; display: none;">
                        <!-- 遍历子菜单 -->
                        <c:forEach items="${p_menu.childs}" var="c_menu">
                            <li style="height: 30px;"><a href="${ctp}/${c_menu.url}" data-action="${c_menu.id}"><i
                                    class="${c_menu.icon}"></i>${c_menu.name}</a></li>
                        </c:forEach>
                    </ul></li>
            </c:forEach>
        </ul>
    </div>
</div>

2、mybatis分页查询

根据用户名或者账号进行查询

效果图:

引入依赖:


<!-- 分页 插件 -->
<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper</artifactId>
</dependency>

业务层:

1)带条件查询


@Override
public List<TUser> getAllUsersByCondition(String str) {
    System.out.println("UserServiceImpl.getAllUsersByCondition 带条件查询员工============>");

    // 查询条件拼接
    // 第一次创建的条件,默认使用and连接的
    TUserExample tUserExample = new TUserExample();
    Criteria criteria = tUserExample.createCriteria();
    Criteria criteria2 = tUserExample.createCriteria();
    if (!str.trim().equals("")) {
        criteria.andLoginacctLike("%" + str + "%");
        criteria.andUsernameLike("%" + str + "%");
    }
    tUserExample.or(criteria2);
    List<TUser> list_users_example = userMapper.selectByExample(tUserExample);
    return list_users_example;
}

控制层:

1)mybatis分页插件会对结果集进行包装,必须在查询前设置: PageHelper.startPage(pn, ps);

2)查询后输入框数据回显:model.addAttribute(“sp”, search);(转发)


@RequestMapping("/list")
public String users(@RequestParam(value = "pn", defaultValue = "1") Integer pn,
        @RequestParam(value = "ps", defaultValue = "5") Integer ps,
        @RequestParam(value = "sp", defaultValue = "") String search, Model model) {
    System.out.println("UserController.users 用户列表显示页===========>");

    System.out.println("前台请求参数[第xxx页,每页显示xxx条数]==========>");
    System.out.println(pn);
    System.out.println(ps);
    // 分页显示数据,这里设置必须放到查询数据之前,否则前台会有问题
    PageHelper.startPage(pn, ps);

    List<TUser> list_users = userService.getAllUsersByCondition(search);
    System.out.println("查询到的所有用户列表========>");
    System.out.println(list_users);

    PageInfo<TUser> users = new PageInfo<>(list_users, 5);
    System.out.println("分页后的数据处理");
    System.out.println(users);
    // 将查询用户列表数据放在请求域中,表单查询参数回显到页面
    model.addAttribute("users", users);
    model.addAttribute("sp", search);

    return "manager/permission/user";
}

前台:

1)为所有分页连接绑定单击事件,让其动态的带上分页的查询参数


var href = $(this).attr("href") + "&sp="+ $("input[name='sp']").val()<br/>
$(this).attr("href", href)

2)全选和全不选函数


//全选/全不选函数
function checkall_reverse(check_all_btn, check_btn) {
    check_all_btn.click(function() {
        //如果是原生的属性,使用prop获取比较好
        check_btn.prop("checked", $(this).prop("checked"))
    })
    check_btn.click(function() {
        //当check_btn点满以后check_all_btn勾上,否则不选中
        //获取被选中的checkbtn个数
        var flag = check_btn.filter(":checked").length == check_btn.length
        check_all_btn.prop("checked", flag);
    })
}



<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html lang="UTF-8">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="">
<meta name="author" content="">


<%@include file="/WEB-INF/includes/css-file.jsp"%>
<link rel="stylesheet" href="${ctp}/css/main.css">
<style>
.tree li {
    list-style-type: none;
    cursor: pointer;
}

table tbody tr:nth-child(odd) {
    background: #F4F4F4;
}

table tbody td:nth-child(even) {
    color: #C00;
}
</style>
</head>

<body>

    <%
        //设置导航条上的显示
                pageContext.setAttribute("navinfo", "用户维护");
                //设置点击高亮效果
                pageContext.setAttribute("curUrl", "permission/user/list");
    %>
    <!-- 引入navbar-->
    <%@include file="/WEB-INF/includes/nav-bar.jsp"%></nav>

    <div class="container-fluid">
        <div class="row">
            <!-- 引入树形菜单 -->
            <%@include file="/WEB-INF/includes/user_menu.jsp"%>
            <div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
                <div class="panel panel-default">
                    <div class="panel-heading">
                        <h3 class="panel-title">
                            <i class="glyphicon glyphicon-th"></i> 数据列表
                        </h3>
                    </div>
                    <div class="panel-body">
                        <form class="form-inline" role="form" style="float: left;"
                            action="${ctp }/permission/user/list" method="post">
                            <div class="form-group has-feedback">
                                <div class="input-group">
                                    <div class="input-group-addon">查询条件</div>
                                    <input class="form-control has-success" type="text" name="sp"
                                        placeholder="用户名/账号查询" value="${sp}">
                                </div>
                            </div>
                            <button type="submit" class="btn btn-warning">
                                <i class="glyphicon glyphicon-search"></i> 查询
                            </button>
                        </form>
                        <button type="button" class="btn btn-danger"
                            style="float: right; margin-left: 10px;">
                            <i class=" glyphicon glyphicon-remove"></i> 删除
                        </button>
                        <button type="button" class="btn btn-primary"
                            style="float: right;" onclick="window.location.href='add.html'">
                            <i class="glyphicon glyphicon-plus"></i> 新增
                        </button>
                        <br>
                        <hr style="clear: both;">
                        <div class="table-responsive">
                            <table class="table  table-bordered">
                                <thead>
                                    <tr>
                                        <th width="30">#</th>
                                        <th width="30"><input type="checkbox" id="checkall_btn"></th>
                                        <th>账号</th>
                                        <th>名称</th>
                                        <th>邮箱地址</th>
                                        <th width="100">操作</th>
                                    </tr>
                                </thead>
                                <tbody>
                                    <c:forEach items="${users.list}" var="user">
                                        <tr>
                                            <td>${user.id}</td>
                                            <td><input type="checkbox" class="single_check"></td>
                                            <td>${user.loginacct }</td>
                                            <td>${user.username }</td>
                                            <td>${user.email }</td>
                                            <td>
                                                <button type="button" class="btn btn-success btn-xs">
                                                    <i class=" glyphicon glyphicon-check"></i>
                                                </button>
                                                <button type="button" class="btn btn-primary btn-xs">
                                                    <i class=" glyphicon glyphicon-pencil"></i>
                                                </button>
                                                <button type="button" class="btn btn-danger btn-xs">
                                                    <i class=" glyphicon glyphicon-remove"></i>
                                                </button>
                                            </td>
                                        </tr>
                                    </c:forEach>
                                </tbody>
                                <tfoot>
                                    <tr>
                                        <td colspan="6" align="center">

                                            <ul class="pagination">
                                                <!-- 即使点击分页连接也应该带上查询条件的值 -->
                                                <!-- 给分页超链接绑定单击事件; -->
                                                <li><a href="${ctp}/permission/user/list?pn=1">首页</a></li>
                                                <!-- 是否还有前一页 -->
                                                <c:if test="${users.hasPreviousPage}">
                                                    <li><a
                                                        href="${ctp}/permission/user/list?pn=${users.prePage}">上一页</a></li>
                                                </c:if>


                                                <!-- 遍历页数 -->
                                                <c:forEach items="${users.navigatepageNums}" var="pn">
                                                    <!-- 当前页 -->
                                                    <c:if test="${pn==users.pageNum }">
                                                        <li class="active"><a
                                                            href="${ctp}/permission/user/list?pn=${pn}">${pn}<span
                                                                class="sr-only">(current)</span></a></li>
                                                    </c:if>
                                                    <c:if test="${pn != users.pageNum }">
                                                        <li><a href="${ctp}/permission/user/list?pn=${pn}">${pn }</a></li>
                                                    </c:if>
                                                </c:forEach>
                                                <!--是否还有下一页  -->
                                                <c:if test="${users.hasNextPage}">
                                                    <li><a
                                                        href="${ctp}/permission/user/list?pn=${users.nextPage}">下一页</a></li>
                                                </c:if>
                                                <li><a
                                                    href="${ctp}/permission/user/list?pn=${users.pages}">末页</a></li>
                                            </ul>
                                        </td>
                                    </tr>

                                </tfoot>
                            </table>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>

    <%@include file="/WEB-INF/includes/js-file.jsp"%>
    <!-- 引入树形菜单结构点击时动态显示页面高亮效果的js -->
    <%@include file="/WEB-INF/includes/common-js.jsp"%>

    <script type="text/javascript">
        $(function() {
            $(".list-group-item").click(function() {
                if ($(this).find("ul")) {
                    $(this).toggleClass("tree-closed");
                    if ($(this).hasClass("tree-closed")) {
                        $("ul", this).hide("fast");
                    } else {
                        $("ul", this).show("fast");
                    }
                }
            });
        });
        $("tbody .btn-success").click(function() {
            window.location.href = "assignRole.html";
        });
        $("tbody .btn-primary").click(function() {
            window.location.href = "edit.html";
        });


        //当前页面所在的哪个超链接是color:red
        //他的父list-group-item.  tree-closed是没有的
        //找到当前页面的a连接
        //使用css为某个元素加样式  list-group-item
        //为所有分页连接绑定单击事件,让其动态的带上分页的查询参数
        $(".pagination").find("a").click(
                function() {
                    //1、获取到查询表单的查询参数
                    //不禁用默认行为,而是为超链接多拼装上查询条件
                    //为超链接动态拼装查询条件
                    var href = $(this).attr("href") + "&sp="
                            + $("input[name='sp']").val()
                    $(this).attr("href", href)
                })

        //这是调用了抽取过来的方法;
        checkall_reverse($("#checkall_btn"), $(".single_check"))
    </script>
</body>
</html>


   转载规则


《ztree树形结构菜单_mybatis分页查询》 shenlibing 采用 知识共享署名 4.0 国际许可协议 进行许可。
  目录