springboot权限设计(经典五张表)数据库到数据封装
数据库表设计
用户表sys_user:
角色表sys_role:
用户角色表user_role:
权限表menu_item:
角色权限表role_menu:
数据库连接查询
SELECT mt.* FROM sys_user u, sys_role r,user_role ur, menu_item mt, role_menu rp WHERE u.loginName = admin AND u.userId = ur.userId AND r.roleId = ur.roleId AND r.roleId = rp.roleId AND mt.itemId = rp.itemId;
对数据库查询到的数据进行进行处理,使它具有树型结构:
权限表实体类MenItem:
public class MenuItem { Integer itemId; String itemName; String itemIcon; String itemUrl; Integer parentId; //get set方法 }
树形结构VO类:
public class MenuTreeVO { Integer itemId; String itemName; String itemIcon; String itemUrl; Integer parentId; List<MenuTreeVO> children; //get和set方法 }
将数据处理为树形的工具类TreeUtil:
public class TreeUtil { /** * 所有待用"菜单" */ private static List<MenuTreeVO> all = null; /** * 转换为树形 * @param list 所有节点 * @return 转换后的树结构菜单 */ public static List<MenuTreeVO> toTree(List<MenuTreeVO> list) { // 最初, 所有的 "菜单" 都是待用的 all = new ArrayList<>(list); // 拿到所有的顶级 "菜单" List<MenuTreeVO> roots = new ArrayList<>(); for (MenuTreeVO menuTreeVO : list) { if (menuTreeVO.getParentId() == 0) { roots.add(menuTreeVO); } } // 将所有顶级菜单从 "待用菜单列表" 中删除 all.removeAll(roots); for (MenuTreeVO menuTreeVO : roots) { menuTreeVO.setChildren(getCurrentNodeChildren(menuTreeVO));; } return roots; } /** * 递归函数 * 递归目的: 拿到子节点 * 递归终止条件: 没有子节点 * @param parent 父节点 * @return 子节点 */ private static List<MenuTreeVO> getCurrentNodeChildren(MenuTreeVO parent) { // 判断当前节点有没有子节点, 没有则创建一个空长度的 List, 有就使用之前已有的所有子节点. List<MenuTreeVO> childList = parent.getChildren() == null ? new ArrayList<>() : parent.getChildren(); // 从 "待用菜单列表" 中找到当前节点的所有子节点 for (MenuTreeVO child : all) { if (parent.getItemId().equals(child.getParentId())) { childList.add(child); } } // 将当前节点的所有子节点从 "待用菜单列表" 中删除 all.removeAll(childList); // 所有的子节点再寻找它们自己的子节点 for (MenuTreeVO menuTreeVO : childList) { menuTreeVO.setChildren(getCurrentNodeChildren(menuTreeVO)); } return childList; } }
使用方法:根据登录名LoginName,查找到用户的权限,将刚才sql执行的结构封装到List<MenuItem>中:
public List<MenuTreeVO> getMenu(String loginName){ List<MenuItem>menus = userMapper.getMenu(loginName); List<MenuTreeVO> menuTreeVOS = new ArrayList<>(); TreeUtil treeUtil= new TreeUtil(); for (MenuItem menu : menus) { MenuTreeVO menuTreeVO = new MenuTreeVO(); BeanUtils.copyProperties(menu, menuTreeVO); menuTreeVOS.add(menuTreeVO); } return TreeUtil.toTree(menuTreeVOS); }
Controller调用这个方法:
@GetMapping("/getmenu") @ApiOperation(value="菜单查询") public ApiResult getuser(@RequestParam String loginName) { List<MenuTreeVO>menu = userService.getMenu(loginName); return ApiResultHandler.buildApiResult(200, "查找成功", menu); }
查询结构均为这样的形式: