JAVA实现从数据库读取菜单,递归生成菜单树

首先这是基于springboot递归生成一个菜单树
如图
在这里插入图片描述
生成的数据结构
在这里插入图片描述
在这里插入图片描述
包结构
在这里插入图片描述

  1. pom.xml
       <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.2</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>

2.我们定义菜单实体类

public class Menu implements Serializable {
    private static final long serialVersionUID = -87667145890581795L;
    
    private Integer id;
    
    private Integer pid;
    /**
    * 权限类型[menu/permission]
    */
    private String type;
    
    private String title;
    /**
    * 权限编码[只有type= permission才有  user:view]
    */
    private String percode;
    
    private String icon;
    
    private String href;
    
    private String target;
    
    private Integer open;
    
    private Integer ordernum;
    /**
    * 状态【0不可用1可用】
    */
    private Integer available;

    private List<Menu> children;

    public List<Menu> getChildren() {
        return children;
    }

    public void setChildren(List<Menu> children) {
        this.children = children;
    }

    @Override
    public String toString() {
        return "Menu{" +
                "id=" + id +
                ", pid=" + pid +
                ", type='" + type + '\'' +
                ", title='" + title + '\'' +
                ", percode='" + percode + '\'' +
                ", icon='" + icon + '\'' +
                ", href='" + href + '\'' +
                ", target='" + target + '\'' +
                ", open=" + open +
                ", ordernum=" + ordernum +
                ", available=" + available +
                ", children=" + children +
                '}';
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public Integer getPid() {
        return pid;
    }

    public void setPid(Integer pid) {
        this.pid = pid;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getPercode() {
        return percode;
    }

    public void setPercode(String percode) {
        this.percode = percode;
    }

    public String getIcon() {
        return icon;
    }

    public void setIcon(String icon) {
        this.icon = icon;
    }

    public String getHref() {
        return href;
    }

    public void setHref(String href) {
        this.href = href;
    }

    public String getTarget() {
        return target;
    }

    public void setTarget(String target) {
        this.target = target;
    }

    public Integer getOpen() {
        return open;
    }

    public void setOpen(Integer open) {
        this.open = open;
    }

    public Integer getOrdernum() {
        return ordernum;
    }

    public void setOrdernum(Integer ordernum) {
        this.ordernum = ordernum;
    }

    public Integer getAvailable() {
        return available;
    }

    public void setAvailable(Integer available) {
        this.available = available;
    }

}
  1. mapper层
@Mapper
/**
 * @author song
 * @data 2020/4/9
 */
@Mapper
public interface MenuMapper {
    /**
     * 查询所有菜单(树状)
     * @return
     */
    List<Menu> findAllMenu();
}
  1. service层
/**
 * @author song
 * @data 2020/4/9
 */
public interface MenuService {
    /**
     * 查询所有菜单(树状)
     * @return
     */
    List<Menu> findAllMenu();
}
  1. serviceimpl层
/**
 * @author song
 * @data 2020/4/9
 */
@Service
public class MenuServiceImpl implements MenuService {
    @Autowired
    MenuMapper menuMapper;

    @Override
    public List<Menu> findAllMenu() {

        List<Menu> menuList = menuMapper.findAllMenu();

        List<Menu> treeNode = buildTree(menuList);
        return treeNode;
    }

    private List<Menu> buildTree(List<Menu> menuList) {
        //创建list集合,用于数据最终封装
        List<Menu> finalNode = new ArrayList<>();

        for (Menu menu : menuList) {
            Integer topId = 0;
            //判断Pid是否等于0  0是最高的节点 将查询出的数据放进list集合
            if (topId.equals(menu.getPid())) {
                finalNode.add(selectTree(menu, menuList));
            }
        }
        return finalNode;
    }

    private Menu selectTree(Menu m1, List<Menu> menuList) {
        //因为向一层菜单里面放二层菜单,二层里面还要放三层,把对象初始化
        m1.setChildren(new ArrayList<Menu>());
        //遍历所有菜单list集合,进行判断比较,比较id和pid值是否相同
        for (Menu m2 : menuList) {
            //判断 id和pid值是否相同
            if (m1.getId().equals(m2.getPid())) {
                //如果children为空,进行初始化操作
                if (m1.getChildren() == null) {
                    m1.setChildren(new ArrayList<Menu>());
                }
                //把查询出来的子菜单放到父菜单里面
                m1.getChildren().add(selectTree(m2, menuList));
            }
        }
        return m1;
    }
}
  1. controller层
/**
 * @author song
 * @data 2020/4/9
 */
@RestController
public class MenuController {

    @Autowired
    MenuService menuService;

    /**
     * 查询所有菜单(树状)
     * @return
     */
    @GetMapping("/")
    public List<Menu> findAllMenu(){
        return menuService.findAllMenu();
    }
}
  1. application properties
# 服务端口
server.port=8001
# mysql数据库连接
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/erp?serverTimezone=GMT%2B8
spring.datasource.username=root
spring.datasource.password=123456
#配置mapper xml文件的路径
mybatis.mapper-locations=classpath:mapper/*.xml




  1. mapper.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.song.recursion.mapper.MenuMapper">
    <select id="findAllMenu" resultType="com.song.recursion.entity.Menu">
        select *from sys_permission
    </select>
</mapper>
  1. 数据表
/*
Navicat MySQL Data Transfer

Source Server         : song
Source Server Version : 80012
Source Host           : 127.0.0.1:3306
Source Database       : erp

Target Server Type    : MYSQL
Target Server Version : 80012
File Encoding         : 65001

Date: 2020-04-09 18:23:43
*/

SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for sys_permission
-- ----------------------------
DROP TABLE IF EXISTS `sys_permission`;
CREATE TABLE `sys_permission` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `pid` int(11) DEFAULT NULL,
  `type` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '权限类型[menu/permission]',
  `title` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
  `percode` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '权限编码[只有type= permission才有  user:view]',
  `icon` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
  `href` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
  `target` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
  `open` int(11) DEFAULT NULL,
  `ordernum` int(11) DEFAULT NULL,
  `available` int(11) DEFAULT NULL COMMENT '状态【0不可用1可用】',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=105 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;

-- ----------------------------
-- Records of sys_permission
-- ----------------------------
INSERT INTO `sys_permission` VALUES ('1', '0', 'menu', '进销存管理系统', null, '&#xe68e;', '', '', '1', '1', '1');
INSERT INTO `sys_permission` VALUES ('2', '1', 'menu', '基础管理', null, '&#xe857;', '', '', '0', '2', '1');
INSERT INTO `sys_permission` VALUES ('3', '1', 'menu', '进货管理', null, '&#xe645;', '', null, '0', '3', '1');
INSERT INTO `sys_permission` VALUES ('4', '1', 'menu', '销售管理', null, '&#xe611;', '', '', '0', '4', '1');
INSERT INTO `sys_permission` VALUES ('5', '1', 'menu', '系统管理', null, '&#xe614;', '', '', '0', '5', '1');
INSERT INTO `sys_permission` VALUES ('6', '1', 'menu', '其它管理', null, '&#xe628;', '', '', '0', '6', '1');
INSERT INTO `sys_permission` VALUES ('7', '2', 'menu', '客户管理', null, '&#xe651;', '/bus/toCustomerManager', '', '0', '7', '1');
INSERT INTO `sys_permission` VALUES ('8', '2', 'menu', '供应商管理', null, '&#xe658;', '/bus/toProviderManager', '', '0', '8', '1');
INSERT INTO `sys_permission` VALUES ('9', '2', 'menu', '商品管理', null, '&#xe657;', '/bus/toGoodsManager', '', '0', '9', '1');
INSERT INTO `sys_permission` VALUES ('10', '3', 'menu', '商品进货', null, '&#xe756;', '/bus/toInportManager', '', '0', '10', '1');
INSERT INTO `sys_permission` VALUES ('11', '3', 'menu', '商品退货查询', null, '&#xe65a;', '/bus/toOutportManager', '', '0', '11', '1');
INSERT INTO `sys_permission` VALUES ('12', '4', 'menu', '商品销售', null, '&#xe65b;', '', '', '0', '12', '1');
INSERT INTO `sys_permission` VALUES ('13', '4', 'menu', '销售退货查询', null, '&#xe770;', '', '', '0', '13', '1');
INSERT INTO `sys_permission` VALUES ('14', '5', 'menu', '部门管理', null, '&#xe770;', '/sys/toDeptManager', '', '0', '14', '1');
INSERT INTO `sys_permission` VALUES ('15', '5', 'menu', '菜单管理', null, '&#xe857;', '/sys/toMenuManager', '', '0', '15', '1');
INSERT INTO `sys_permission` VALUES ('16', '5', 'menu', '权限管理', '', '&#xe857;', '/sys/toPermissionManager', '', '0', '16', '1');
INSERT INTO `sys_permission` VALUES ('17', '5', 'menu', '角色管理', '', '&#xe650;', '/sys/toRoleManager', '', '0', '17', '1');
INSERT INTO `sys_permission` VALUES ('18', '5', 'menu', '用户管理', '', '&#xe612;', '/sys/toUserManager', '', '0', '18', '1');
INSERT INTO `sys_permission` VALUES ('21', '6', 'menu', '登陆日志', null, '&#xe675;', '/sys/toLoginfoManager', '', '0', '21', '1');
INSERT INTO `sys_permission` VALUES ('22', '6', 'menu', '系统公告', null, '&#xe756;', '/sys/toNoticeManager', null, '0', '22', '1');
INSERT INTO `sys_permission` VALUES ('23', '6', 'menu', '图标管理', null, '&#xe670;', '../resources/page/icon.html', null, '0', '23', '1');
INSERT INTO `sys_permission` VALUES ('30', '14', 'permission', '添加部门', 'dept:create', '', null, null, '0', '24', '1');
INSERT INTO `sys_permission` VALUES ('31', '14', 'permission', '修改部门', 'dept:update', '', null, null, '0', '26', '1');
INSERT INTO `sys_permission` VALUES ('32', '14', 'permission', '删除部门', 'dept:delete', '', null, null, '0', '27', '1');
INSERT INTO `sys_permission` VALUES ('34', '15', 'permission', '添加菜单', 'menu:create', '', '', '', '0', '29', '1');
INSERT INTO `sys_permission` VALUES ('35', '15', 'permission', '修改菜单', 'menu:update', '', null, null, '0', '30', '1');
INSERT INTO `sys_permission` VALUES ('36', '15', 'permission', '删除菜单', 'menu:delete', '', null, null, '0', '31', '1');
INSERT INTO `sys_permission` VALUES ('38', '16', 'permission', '添加权限', 'permission:create', '', null, null, '0', '33', '1');
INSERT INTO `sys_permission` VALUES ('39', '16', 'permission', '修改权限', 'permission:update', '', null, null, '0', '34', '1');
INSERT INTO `sys_permission` VALUES ('40', '16', 'permission', '删除权限', 'permission:delete', '', null, null, '0', '35', '1');
INSERT INTO `sys_permission` VALUES ('42', '17', 'permission', '添加角色', 'role:create', '', null, null, '0', '37', '1');
INSERT INTO `sys_permission` VALUES ('43', '17', 'permission', '修改角色', 'role:update', '', null, null, '0', '38', '1');
INSERT INTO `sys_permission` VALUES ('44', '17', 'permission', '角色删除', 'role:delete', '', null, null, '0', '39', '1');
INSERT INTO `sys_permission` VALUES ('46', '17', 'permission', '分配权限', 'role:selectPermission', '', null, null, '0', '41', '1');
INSERT INTO `sys_permission` VALUES ('47', '18', 'permission', '添加用户', 'user:create', '', null, null, '0', '42', '1');
INSERT INTO `sys_permission` VALUES ('48', '18', 'permission', '修改用户', 'user:update', '', null, null, '0', '43', '1');
INSERT INTO `sys_permission` VALUES ('49', '18', 'permission', '删除用户', 'user:delete', '', null, null, '0', '44', '1');
INSERT INTO `sys_permission` VALUES ('51', '18', 'permission', '用户分配角色', 'user:selectRole', '', null, null, '0', '46', '1');
INSERT INTO `sys_permission` VALUES ('52', '18', 'permission', '重置密码', 'user:resetPwd', null, null, null, '0', '47', '1');
INSERT INTO `sys_permission` VALUES ('53', '14', 'permission', '部门查询', 'dept:view', null, null, null, '0', '48', '1');
INSERT INTO `sys_permission` VALUES ('54', '15', 'permission', '菜单查询', 'menu:view', null, null, null, '0', '49', '1');
INSERT INTO `sys_permission` VALUES ('55', '16', 'permission', '权限查询', 'permission:view', null, null, null, '0', '50', '1');
INSERT INTO `sys_permission` VALUES ('56', '17', 'permission', '角色查询', 'role:view', null, null, null, '0', '51', '1');
INSERT INTO `sys_permission` VALUES ('57', '18', 'permission', '用户查询', 'user:view', null, null, null, '0', '52', '1');
INSERT INTO `sys_permission` VALUES ('68', '7', 'permission', '客户查询', 'customer:view', null, null, null, null, '60', '1');
INSERT INTO `sys_permission` VALUES ('69', '7', 'permission', '客户添加', 'customer:create', null, null, null, null, '61', '1');
INSERT INTO `sys_permission` VALUES ('70', '7', 'permission', '客户修改', 'customer:update', null, null, null, null, '62', '1');
INSERT INTO `sys_permission` VALUES ('71', '7', 'permission', '客户删除', 'customer:delete', null, null, null, null, '63', '1');
INSERT INTO `sys_permission` VALUES ('73', '21', 'permission', '日志查询', 'info:view', null, null, null, null, '65', '1');
INSERT INTO `sys_permission` VALUES ('74', '21', 'permission', '日志删除', 'info:delete', null, null, null, null, '66', '1');
INSERT INTO `sys_permission` VALUES ('75', '21', 'permission', '日志批量删除', 'info:batchdelete', null, null, null, null, '67', '1');
INSERT INTO `sys_permission` VALUES ('76', '22', 'permission', '公告查询', 'notice:view', null, null, null, null, '68', '1');
INSERT INTO `sys_permission` VALUES ('77', '22', 'permission', '公告添加', 'notice:create', null, null, null, '0', '69', '1');
INSERT INTO `sys_permission` VALUES ('78', '22', 'permission', '公告修改', 'notice:update', null, null, null, null, '70', '1');
INSERT INTO `sys_permission` VALUES ('79', '22', 'permission', '公告删除', 'notice:delete', null, null, null, null, '71', '1');
INSERT INTO `sys_permission` VALUES ('81', '8', 'permission', '供应商查询', 'provider:view', null, null, null, null, '73', '1');
INSERT INTO `sys_permission` VALUES ('82', '8', 'permission', '供应商添加', 'provider:create', null, null, null, null, '74', '1');
INSERT INTO `sys_permission` VALUES ('83', '8', 'permission', '供应商修改', 'provider:update', null, null, null, null, '75', '1');
INSERT INTO `sys_permission` VALUES ('84', '8', 'permission', '供应商删除', 'provider:delete', null, null, null, null, '76', '1');
INSERT INTO `sys_permission` VALUES ('86', '22', 'permission', '公告查看', 'notice:viewnotice', null, null, null, null, '78', '1');
INSERT INTO `sys_permission` VALUES ('91', '9', 'permission', '商品查询', 'goods:view', null, null, null, '0', '79', '1');
INSERT INTO `sys_permission` VALUES ('92', '9', 'permission', '商品添加', 'goods:create', null, null, null, '0', '80', '1');
INSERT INTO `sys_permission` VALUES ('94', '9', 'permission', '商品修改', 'goods:update', null, 'goods:update', null, '0', '81', '1');
INSERT INTO `sys_permission` VALUES ('95', '6', 'menu', '缓存管理', null, '&#xe681;', '/sys/toCacheManager', '', '1', '82', '1');
INSERT INTO `sys_permission` VALUES ('102', '22', 'permission', '公告批量删除', 'notice:batchdelete', null, null, null, '0', '83', '1');
INSERT INTO `sys_permission` VALUES ('103', '7', 'permission', '批量删除客户', 'customer:batchDelete', null, null, null, '0', '84', '1');
INSERT INTO `sys_permission` VALUES ('104', '8', 'permission', '批量删除供应商', 'provider:batchDelete', null, null, null, '0', '85', '1');

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
假设我们有以下的菜单结构: ``` - 菜单1 - 子菜单1.1 - 子菜单1.2 - 孙菜单1.2.1 - 孙菜单1.2.2 - 菜单2 - 子菜单2.1 ``` 我们可以定义一个 Menu 类来表示每个菜单项: ```java class Menu { String name; List<Menu> children; public Menu(String name) { this.name = name; children = new ArrayList<>(); } // 添加子菜单 public void addChild(Menu menu) { children.add(menu); } } ``` 接下来,我们可以使用归的方式来打印整个菜单: ```java class TreeMenu { public static void printMenu(Menu menu, int level) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < level; i++) { sb.append("-"); } sb.append(menu.name); System.out.println(sb.toString()); // 归打印子菜单 for (Menu childMenu : menu.children) { printMenu(childMenu, level + 1); } } } public class Main { public static void main(String[] args) { // 构建菜单 Menu menu1 = new Menu("菜单1"); Menu menu11 = new Menu("子菜单1.1"); Menu menu12 = new Menu("子菜单1.2"); Menu menu121 = new Menu("孙菜单1.2.1"); Menu menu122 = new Menu("孙菜单1.2.2"); menu12.addChild(menu121); menu12.addChild(menu122); menu1.addChild(menu11); menu1.addChild(menu12); Menu menu2 = new Menu("菜单2"); Menu menu21 = new Menu("子菜单2.1"); menu2.addChild(menu21); // 打印菜单 TreeMenu.printMenu(menu1, 0); TreeMenu.printMenu(menu2, 0); } } ``` 输出结果为: ``` -菜单1 --子菜单1.1 --子菜单1.2 ---孙菜单1.2.1 ---孙菜单1.2.2 -菜单2 --子菜单2.1 ``` 我们通过归遍历整棵,按照菜单层级打印每个菜单项的名称,并加上相应的缩进。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值