1.說明
根據用戶角色的權限進行菜單管理,根據擁有的權限訪問范圍內的菜單
2.數據庫表設計
2.1用戶表
CREATE TABLE `sys_user` ( `uid` int(11) NOT NULL AUTO_INCREMENT COMMENT '用戶Id', `username` varchar(100) NOT NULL COMMENT '用戶名', `password` varchar(100) NOT NULL COMMENT '密碼', `phone` varchar(11) DEFAULT NULL COMMENT '手機', `email` varchar(100) DEFAULT NULL COMMENT '郵箱', `locked` int(1) DEFAULT NULL COMMENT '賬號是否被鎖定', PRIMARY KEY (`uid`), UNIQUE KEY `uk_u_1` (`username`) ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8
2.2角色表
Create Table CREATE TABLE `sys_role` ( `roleId` int(11) NOT NULL AUTO_INCREMENT COMMENT '角色Id', `roleName` varchar(100) DEFAULT NULL COMMENT '角色名稱', `roleDesc` varchar(100) DEFAULT NULL COMMENT '角色描述', `role` varchar(100) DEFAULT NULL COMMENT '角色標志', PRIMARY KEY (`roleId`) ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8
2.3權限表
Create Table CREATE TABLE `sys_permission` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '權限Id', `pdesc` varchar(100) DEFAULT NULL COMMENT '權限描述', `name` varchar(100) DEFAULT NULL COMMENT '權限名稱', `menuId` int(11) DEFAULT NULL COMMENT '菜單Id', PRIMARY KEY (`id`), KEY `p_fk_1` (`menuId`), CONSTRAINT `p_fk_1` FOREIGN KEY (`menuId`) REFERENCES `sys_menu` (`menuId`) ) ENGINE=InnoDB AUTO_INCREMENT=16 DEFAULT CHARSET=utf8
2.4菜單表
CREATE TABLE `sys_menu` ( `menuId` int(11) NOT NULL AUTO_INCREMENT COMMENT '菜單Id', `parentId` int(11) DEFAULT NULL COMMENT '上級Id', `menuName` varchar(100) DEFAULT NULL COMMENT '菜單名稱', `menuUrl` varchar(100) DEFAULT NULL COMMENT '菜單鏈接', `menuStatus` varchar(10) DEFAULT NULL COMMENT '菜單狀態', `level` int(4) NOT NULL COMMENT '菜單等級', PRIMARY KEY (`menuId`) ) ENGINE=InnoDB AUTO_INCREMENT=16 DEFAULT CHARSET=utf8
3.代碼
3.1設計思路
本次菜單只有兩級,所有采用hashmap方式解決,Map<String, List<SysMenu>>,key值為父菜單,value為子菜單集合.
dao層:根據用戶登錄的session值取到用戶id,根據用戶id關聯查詢出所有菜單列表(包括父子菜單)
service層:雙層for循環,判斷menuById.get(I).getParentid() == 0且menuById.get(I).getMenuid() == menuById.get(J).getParentid();這樣就可以得到父菜單及其子菜單,
將子菜單對象放在list集合中,在將父菜單的name作為key,子菜單的集合作為value存入map中;如圖可以看出端倪:
servlet層:獲取登陸后session中保存的uid,調用service方法.返回主頁面;
前端:el表達式,雙重foreach,動態展示各父菜單及子菜單
3.2.dao層
QueryRunner queryRunner = new QueryRunner(ComboPooledDataSourceUtil.getDataSourceByxml());
List<Object> param = new ArrayList<>();
StringBuffer buffer = new StringBuffer();
@Override public List<SysMenu> findMenuById(Integer uid) { //清空list和stringbuffer delListAndStringBuf(); buffer.append("SELECT m.*"); buffer.append(" FROM `sys_user` u"); buffer.append(" INNER JOIN `sys_user_role` ur"); buffer.append(" ON u.`uid`=ur.`userId`"); buffer.append(" INNER JOIN `sys_role` r"); buffer.append(" ON ur.`roleId`=r.`roleId`"); buffer.append(" INNER JOIN `sys_role_permission` rp"); buffer.append(" ON r.`roleId`=rp.`roleId`"); buffer.append(" INNER JOIN `sys_permission` p"); buffer.append(" ON rp.`permissionId`=p.`id`"); buffer.append(" JOIN`sys_menu` m"); buffer.append(" ON m.`menuId`=p.`menuId`"); buffer.append(" WHERE m.`menuStatus`=0"); buffer.append(" AND u.`locked`=0"); buffer.append(" AND u.`uid`=?"); param.add(uid); //list集合轉化為數組 Object[] objects = param.toArray(); List<SysMenu> menu =null; // try { menu = queryRunner.query(buffer.toString(), new BeanListHandler<SysMenu>(SysMenu.class), objects); } catch (SQLException e) { } return menu; }
//清空list和stringbuffer
public void delListAndStringBuf(){
param.clear();
buffer.delete(0,buffer.length());
}
3.3.service層
@Override public Map<String, List<SysMenu>> menus(Integer uid) { //key為父菜單,value為父菜單下的子菜單集合 Map<String, List<SysMenu>> menus = new HashMap<>(); //父子菜單集合 List<SysMenu> menuById = permissionMenuDao.findMenuById(uid); for (int i = 0; i < menuById.size(); i++) { //子菜單集合,外層循環時為另外一個父菜單的子菜單 List<SysMenu> childMenu = new ArrayList<>(); for (int j = 0; j < menuById.size(); j++) { //SysMenu創建對象,二次循環時為同父菜單下的另外一個子菜單對象 SysMenu sm = new SysMenu(); if (menuById.get(i).getParentid() == 0 & menuById.get(i).getMenuid() == menuById.get(j).getParentid()) { sm.setMenuname(menuById.get(j).getMenuname()); sm.setMenuurl(menuById.get(j).getMenuurl()); sm.setMenuid(menuById.get(j).getMenuid()); // childMenu對象 childMenu.add(sm); //將父菜單以及對應的子菜單集合封裝在map里面 menus.put(menuById.get(i).getMenuname(), childMenu); } } } return menus; }
3.4servlet層
@WebServlet("/main/") public class PermissionMenuServlet extends BaseServlet { PermissionMenuService service=new PermissionMenuServiceImpl(); public String index (HttpServletRequest request, HttpServletResponse response){ HttpSession session = request.getSession(); SysUser user= (SysUser) session.getAttribute("user"); System.out.println("user:"+user.getUid()); Map<String, List<SysMenu>> menus = service.menus(user.getUid()); request.setAttribute("menus",menus); return "/WEB-INF/views/main/mainpage.jsp"; } }
4.0 前端
<aside class="Hui-aside"> <div class="menu_dropdown bk_2"> <%--父菜單--%> <c:forEach items="${requestScope.menus}" var="mainMenu"> <dl id="menu-article"> <dt><i class="Hui-iconfont"></i> ${mainMenu.key}<i class="Hui-iconfont menu_dropdown-arrow"></i></dt> <dd> <%--子菜單--%> <c:forEach items="${mainMenu.value}" var="childMenu"> <ul> <li><a data-href=${childMenu.menuurl} data-title=${childMenu.menuname} href="javascript:void(0)">${childMenu.menuname}</a></li> </ul> </c:forEach> </dd> </dl> </c:forEach> </div> </aside>
備注:登錄的service層需加入在session中加入uid
request.getSession().setAttribute("user",user);