IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> 【一】springboot+mysql+mybatis实现菜单树(超详细) -> 正文阅读

[Java知识库]【一】springboot+mysql+mybatis实现菜单树(超详细)

springboot+mysql+mybatis实现菜单树(超详细)

在项目中常常能用到菜单树,今天就带大家自己实现一个


这个是我的目录结构

在这里插入图片描述

一、mysql 表

首先我们先建立一张表, 这个是菜单表,主要 两个字段就是menu_id 和 parent_id这两个字段

DROP TABLE IF EXISTS `sys_menu`;
CREATE TABLE `sys_menu`  (
  `menu_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '菜单ID',
  `menu_name` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '菜单名称',
  `parent_id` bigint(20) NULL DEFAULT 0 COMMENT '父菜单ID',
  `order_num` int(4) NULL DEFAULT 0 COMMENT '显示顺序',
  `url` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT '#' COMMENT '请求地址',
  `target` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT '' COMMENT '打开方式(menuItem页签 menuBlank新窗口)',
  `menu_type` char(1) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT '' COMMENT '菜单类型(M目录 C菜单 F按钮)',
  `visible` char(1) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT '0' COMMENT '菜单状态(0显示 1隐藏)',
  `is_refresh` char(1) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT '1' COMMENT '是否刷新(0刷新 1不刷新)',
  `perms` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '权限标识',
  `icon` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT '#' COMMENT '菜单图标',
  `create_by` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT '' COMMENT '创建者',
  `create_time` datetime(0) NULL DEFAULT NULL COMMENT '创建时间',
  `update_by` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT '' COMMENT '更新者',
  `update_time` datetime(0) NULL DEFAULT NULL COMMENT '更新时间',
  `remark` varchar(500) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT '' COMMENT '备注',
  PRIMARY KEY (`menu_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1062 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '菜单权限表' ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of sys_menu
-- ----------------------------
INSERT INTO `sys_menu` VALUES (1, '系统管理', 0, 1, '#', '', 'M', '0', '1', '', 'fa fa-gear', 'admin', '2022-08-09 13:41:06', '', NULL, '系统管理目录');
INSERT INTO `sys_menu` VALUES (2, '系统监控', 0, 2, '#', '', 'M', '0', '1', '', 'fa fa-video-camera', 'admin', '2022-08-09 13:41:06', '', NULL, '系统监控目录');
INSERT INTO `sys_menu` VALUES (100, '用户管理', 1, 1, '/system/user', '', 'C', '0', '1', 'system:user:view', 'fa fa-user-o', 'admin', '2022-08-09 13:41:06', '', NULL, '用户管理菜单');
INSERT INTO `sys_menu` VALUES (113, '缓存监控', 2, 5, '/monitor/cache', '', 'C', '0', '1', 'monitor:cache:view', 'fa fa-cube', 'admin', '2022-08-09 13:41:06', '', NULL, '缓存监控菜单');
INSERT INTO `sys_menu` VALUES (114, '表单构建', 3, 1, '/tool/build', '', 'C', '0', '1', 'tool:build:view', 'fa fa-wpforms', 'admin', '2022-08-09 13:41:06', '', NULL, '表单构建菜单');
INSERT INTO `sys_menu` VALUES (501, '登录日志', 108, 2, '/monitor/logininfor', '', 'C', '0', '1', 'monitor:logininfor:view', 'fa fa-file-image-o', 'admin', '2022-08-09 13:41:06', '', NULL, '登录日志菜单');
INSERT INTO `sys_menu` VALUES (1000, '用户查询', 100, 1, '#', '', 'F', '0', '1', 'system:user:list', '#', 'admin', '2022-08-09 13:41:06', '', NULL, '');
INSERT INTO `sys_menu` VALUES (1012, '菜单查询', 102, 1, '#', '', 'F', '0', '1', 'system:menu:list', '#', 'admin', '2022-08-09 13:41:06', '', NULL, '');
INSERT INTO `sys_menu` VALUES (1016, '部门查询', 103, 1, '#', '', 'F', '0', '1', 'system:dept:list', '#', 'admin', '2022-08-09 13:41:06', '', NULL, '');
INSERT INTO `sys_menu` VALUES (1021, '岗位新增', 104, 2, '#', '', 'F', '0', '1', 'system:post:add', '#', 'admin', '2022-08-09 13:41:06', '', NULL, '');
INSERT INTO `sys_menu` VALUES (1022, '岗位修改', 104, 3, '#', '', 'F', '0', '1', 'system:post:edit', '#', 'admin', '2022-08-09 13:41:06', '', NULL, '');
INSERT INTO `sys_menu` VALUES (1026, '字典新增', 105, 2, '#', '', 'F', '0', '1', 'system:dict:add', '#', 'admin', '2022-08-09 13:41:06', '', NULL, '');
INSERT INTO `sys_menu` VALUES (1027, '字典修改', 105, 3, '#', '', 'F', '0', '1', 'system:dict:edit', '#', 'admin', '2022-08-09 13:41:06', '', NULL, '');
INSERT INTO `sys_menu` VALUES (1057, '生成查询', 115, 1, '#', '', 'F', '0', '1', 'tool:gen:list', '#', 'admin', '2022-08-09 13:41:06', '', NULL, '');

SET FOREIGN_KEY_CHECKS = 1;

二、建立controller、service、entity、mapper等

1.controller层

代码如下(示例):


@AllArgsConstructor
public class SysMenuRestController {

    private final SysMenuService sysMenuService;
  
  
    @GetMapping("/queryTreeMenu")
    public AjaxResult queryTreeMenu() {
        List<SysMenu> sysMenus = sysMenuService.queryAll();
        return AjaxResult.success(sysMenus);

    }

2.service层

代码如下(示例):

public interface SysMenuService extends IService<SysMenu> {
    /**
     * @return 返回所有数据
     */
    List<SysMenu> queryAll();

3.impl层

代码如下(示例): 这个注释我写的很明白,一看就懂

@Service
@AllArgsConstructor
public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> implements  SysMenuService {
    private final SysMenuMapper sysMenuMapper;
   

    @Override
    public List<SysMenu> queryAll() {
        //只有主菜单
        List<SysMenu> menusBase = sysMenuMapper.queryById(0);
        //所有的菜单
        List<SysMenu> menuNotBase = sysMenuMapper.queryAllNotBase();
        for (SysMenu sysMenu : menusBase) {
            //返回主菜单的子菜单
            List<SysMenu> menus = iterateMenus(menuNotBase, sysMenu.getMenuId());
            sysMenu.setMenuChildren(menus);
        }
        return menusBase;
    }
    /**
     * @param sysMenuList 所有菜单
     * @param menuId id
     * @return 返回
     */
    public List<SysMenu> iterateMenus(List<SysMenu> sysMenuList, Long menuId) {
        List<SysMenu> result = new ArrayList<>();
        //得到对象
        for (SysMenu sysMenu : sysMenuList) {
            //获取菜单的id
            Long menuIds = sysMenu.getMenuId();
            //获取菜单的父id
            String parentId = String.valueOf(sysMenu.getParentId());
            if (StringUtils.isNotBlank(parentId)) {
                if (parentId.equals(String.valueOf(menuId))) {
                    //递归查询当前子菜单的子菜单
                    List<SysMenu> iterateMenu = iterateMenus(sysMenuList, menuIds);
                    sysMenu.setMenuChildren(iterateMenu);
                    result.add(sysMenu);
                }
            }
        }
        return result;
    }
}

4.mapper层

代码如下(示例):

public interface SysMenuMapper extends BaseMapper<SysMenu> {

    /**
     * 根据父类id查询子类菜单
     * @param pid  父类id
     * @return 数据
     */
    List<SysMenu> queryById(Integer pid);
    /**
     * @return 除一级菜单数据
     */
    List<SysMenu> queryAllNotBase();
}

5.xml

代码如下(示例):

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.study.pc.mapper.SysMenuMapper">

    <!-- 通用查询映射结果 -->
    <resultMap id="BaseResultMap" type="com.study.pc.entity.SysMenu">
        <id column="menu_id" property="menuId" />
        <result column="menu_name" property="menuName" />
        <result column="parent_id" property="parentId" />
        <result column="order_num" property="orderNum" />
        <result column="path" property="path" />
        <result column="component" property="component" />
        <result column="query" property="query" />
        <result column="is_frame" property="isFrame" />
        <result column="is_cache" property="isCache" />
        <result column="menu_type" property="menuType" />
        <result column="visible" property="visible" />
        <result column="status" property="status" />
        <result column="perms" property="perms" />
        <result column="icon" property="icon" />
        <result column="create_by" property="createBy" />
        <result column="create_time" property="createTime" />
        <result column="update_by" property="updateBy" />
        <result column="update_time" property="updateTime" />
        <result column="remark" property="remark" />
    </resultMap>

    <!-- 通用查询结果列 -->
    <sql id="Base_Column_List">
        menu_id, menu_name, parent_id, order_num, path, component, query, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark
    </sql>

    <select id="queryById" resultType="com.study.pc.entity.SysMenu">
        SELECT * FROM sys_menu WHERE menu_id is not null
        <if test="pid != null">
            AND parent_id = #{pid}
        </if>

    </select>
    <select id="queryAll" resultType="com.study.pc.entity.SysMenu">
        SELECT * FROM sys_menu
    </select>
    <select id="queryAllNotBase" resultType="com.study.pc.entity.SysMenu">
        SELECT * FROM sys_menu WHERE parent_id != 0
    </select>


</mapper>

entity 实体层

代码如下(示例):

@Data
@EqualsAndHashCode(callSuper = false)
@TableName("sys_menu")
public class SysMenu extends Model<SysMenu> {

    private static final long serialVersionUID = 1L;
    /**
     * 菜单ID
     */
      @TableId(value = "menu_id", type = IdType.AUTO)
    private Long menuId;
    /**
     * 菜单名称
     */
    private String menuName;
    /**
     * 父菜单ID
     */
    private Long parentId;
    /**
     * 显示顺序
     */
    private Integer orderNum;
    /**
     * 路由地址
     */
    private String path;
    /**
     * 组件路径
     */
    private String component;
    /**
     * 路由参数
     */
    private String query;
    /**
     * 是否为外链(0是 1否)
     */
    private Integer isFrame;
    /**
     * 是否缓存(0缓存 1不缓存)
     */
    private Integer isCache;
    /**
     * 菜单类型(M目录 C菜单 F按钮)
     */
    private String menuType;
    /**
     * 菜单状态(0显示 1隐藏)
     */
    private String visible;
    /**
     * 菜单状态(0正常 1停用)
     */
    private String status;
    /**
     * 权限标识
     */
    private String perms;
    /**
     * 菜单图标
     */
    private String icon;
    /**
     * 创建者
     */
    private String createBy;
    /**
     * 创建时间
     */
    private Date createTime;
    /**
     * 更新者
     */
    private String updateBy;
    /**
     * 更新时间
     */
    private Date updateTime;
    /**
     * 备注
     */
    private String remark;
    //子菜单
    private List<SysMenu> menuChildren;
    @Override
    protected Serializable pkVal() {
        return this.menuId;
    }

}

测试

测试结果正确

在这里插入图片描述

总结

其实这个很简单,没有什么逻辑。
主要的逻辑就是在 service层
xml中其实只做了查询 一个是查询一级菜单,另一个是查询子菜单

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-08-19 18:50:24  更:2022-08-19 18:54:05 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/18 5:17:10-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码