2022.4.8工作总结(逐句解析递归)

本文详细介绍了如何使用Spring Boot实现递归查询和删除数据库中的菜单结构,包括1对多和多对多关系处理,以及利用递归算法查询各级菜单。还涵盖了Swagger配置和角色权限分配,提供示例代码和关键概念解析。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.数据库表

如果是1对多的关系,在多的来个字段。

如果是多对多那就得建立第三章表。

2.递归菜单查询(递归:自己查自己)

(1)level为1就是1级,children就是这一级的子菜单

(2)现有数据才能递归

(3)递归需要有入口,即从哪里开始查起

具体实现:

(1)递归的查询

完整代码如下(解析在下面)


    //========================递归查询所有菜单===========
    //获取全部菜单
    @Override
    public List<Permission> queryAllMenuGuli() {
        //1 查询菜单表所有数据
        QueryWrapper<Permission> wrapper = new QueryWrapper<>();
        wrapper.orderByDesc("id");
        List<Permission> permissionList = baseMapper.selectList(wrapper);
        //2 把查询所有菜单list集合按照要求进行封装
        List<Permission> resultList = bulidPermission(permissionList);
        return resultList;
    }

    //把返回所有菜单list集合进行封装的方法
    public static List<Permission> bulidPermission(List<Permission> permissionList) {

        //创建list集合,用于数据最终封装
        List<Permission> finalNode = new ArrayList<>();
        //把所有菜单list集合遍历,得到顶层菜单 pid=0菜单,设置level是1
        for(Permission permissionNode : permissionList) {
            //得到顶层菜单 pid=0菜单
            if("0".equals(permissionNode.getPid())) {
                //设置顶层菜单的level是1
                permissionNode.setLevel(1);
                //根据顶层菜单,向里面进行查询子菜单,封装到finalNode里面
                //permissionNode这个是level为1的所有数据
                finalNode.add(selectChildren(permissionNode,permissionList));
            }
        }
        return finalNode;
    }
//这个是查询二级和三级菜单:
    private static Permission selectChildren(Permission permissionNode, List<Permission> permissionList) {
        //1 因为向一层菜单里面放二层菜单,二层里面还要放三层,把对象初始化
        permissionNode.setChildren(new ArrayList<Permission>());

        //2 遍历所有菜单list集合,进行判断比较,比较id和pid值是否相同
        for(Permission it : permissionList) {
            //判断 id和pid值是否相同
            if(permissionNode.getId().equals(it.getPid())) {
                //把父菜单的level值+1
                int level = permissionNode.getLevel()+1;
                it.setLevel(level);
                //如果children为空,进行初始化操作
                if(permissionNode.getChildren() == null) {
                    permissionNode.setChildren(new ArrayList<Permission>());
                }
                //把查询出来的子菜单放到父菜单里面
                permissionNode.getChildren().add(selectChildren(it,permissionList));
            }
        }
        return permissionNode;
    }

    //========================递归查询所有菜单
    先获取全部菜单,然后再进行查询
    @Override
    public List<Permission> queryAllMenuGuli() {
        //1 查询菜单表所有数据
        QueryWrapper<Permission> wrapper = new QueryWrapper<>();
        wrapper.orderByDesc("id");
        List<Permission> 所有内容(未封装) = baseMapper.selectList(wrapper);
        //2 把查询所有菜单list集合按照要求进行封装
        List<Permission> resultList = bulidPermission(所有内容(未封装));
        return resultList;
    }

    //把返回所有菜单list集合进行封装的方法
    public static List<Permission> bulidPermission(List<Permission> permissionList【所有内容(未封装)】) {

        //创建list集合,用于数据最终封装
        List<Permission> finalNode 【所有内容(已封装)】= new ArrayList<>();
        //把所有菜单list集合遍历,得到顶层菜单 pid=0菜单,设置level是1
        for(Permission permissionNode【一级菜单】 : permissionList) {
            //得到顶层菜单 pid=0菜单
            if("0".equals(permissionNode.getPid())) {
                //设置顶层菜单的level是1
                permissionNode.setLevel(1);
                //根据顶层菜单,向里面进行查询子菜单,封装到finalNode里面
                //permissionNode这个是level为1的所有数据
                finalNode所有内容(已封装).add(selectChildren(新建的方法)(permissionNode【一级菜单】,permissionList【所有内容(未封装)】));--这是要准备进行递归了
            }
        }
        return finalNode;
    }
//这个是查询二级和三级菜单:
    private static Permission selectChildren(permissionNode【一级菜单】,permissionList【所有内容(未封装)】) {
        //1 因为向一层菜单里面放二层菜单,二层里面还要放三层,把对象初始化
        permissionNode.setChildren(new ArrayList<Permission>());

        //2 遍历所有菜单list集合,进行判断比较,比较id和pid值是否相同
        for(Permission it【二菜单的内容】 : permissionList【所有内容(未封装)】) {
            //判断 id和pid值是否相同
            if(permissionNode【一级菜单】.getId().equals(it【二菜单的内容】.getPid())) {
                //把父菜单的level值+1
                int level = permissionNode.getLevel()+1;
                it.setLevel(level);
                //如果children为空,进行初始化操作
                if(permissionNode.getChildren() == null) {
                    permissionNode.setChildren(new ArrayList<Permission>());
                }--锦上添花,没有也可以

                //把查询出来的子菜单放到父菜单里面
                permissionNode【一级菜单】.getChildren().add(selectChildren(it【二菜单的内容】,permissionList【所有内容(未封装)】));--接下来就是循环上面的步骤
            }
        }
        return permissionNode【一级菜单】;
    }

(2)递归删除

完整代码如下

    //============递归删除菜单==================================
    @Override
    public void removeChildByIdGuli(String id) {
        //1 创建list集合,用于封装所有删除菜单id值
        List<String> idList = new ArrayList<>();
        //2 向idList集合设置删除菜单id,(根据Id删除菜单)				
        this.selectPermissionChildById(id,idList);
        //把当前id封装到list里面
        idList.add(id);
        baseMapper.deleteBatchIds(idList);//以终为始,我最后是要上去删除一个集合,所以在上面新建了一个集合
    }

    //2 根据当前菜单id,查询菜单里面子菜单id,封装到list集合
    private void selectPermissionChildById(String id, List<String> idList) {
        //查询菜单里面子菜单id
        QueryWrapper<Permission>  wrapper = new QueryWrapper<>();
        wrapper.eq("pid",id);
        wrapper.select("id");
        List<Permission> childIdList = baseMapper.selectList(wrapper);
        //把childIdList里面菜单id值获取出来,封装idList里面,做递归查询
        childIdList.stream().forEach(item -> {
            //封装idList里面
            idList.add(item.getId());//通过Id批量查询,因为上面是deleteBatchIds(idList)
            //递归查询
            this.selectPermissionChildById(item.getId(),idList);
        });
    }

    //============递归删除菜单==================================
    @Override
    public void removeChildByIdGuli(String id) {
        //1 创建list集合,用于封装所有删除菜单id值
        List<String> idList【封装要删除的Id】 = new ArrayList<>();
        //2 向idList集合设置删除菜单id,(根据Id删除菜单)                
        this.selectPermissionChildById(id,idList);
        //把当前id封装到list里面
        idList【封装要删除的Id】 .add(id);
        baseMapper.deleteBatchIds(idList【封装要删除的Id】 );//以终为始,我最后是要上去删除一个集合,所以在上面新建了一个集合
    }

    //2 根据当前菜单id,查询菜单里面子菜单id,封装到list集合
    private void selectPermissionChildById(String id, List<String> idList【封装要删除的Id】) {
        //查询菜单里面子菜单id
        QueryWrapper<Permission>  wrapper = new QueryWrapper<>();
        wrapper.eq("pid【1级Id】 ",id【2级Id】);
        wrapper.select("id");//把所有2级id里是1级id的id都筛选出来
        List<Permission> childIdList = baseMapper.selectList(wrapper);//【符合上述条件的2级Id】
        //把childIdList里面菜单id值获取出来,封装idList里面,做递归查询
        childIdList.stream().forEach(item -> {
            //封装idList里面
            idList【封装要删除的Id】.add(item.getId());//通过Id批量查询,因为上面是deleteBatchIds(idList)
            //递归查询
            this.selectPermissionChildById(item.getId()【符合上述条件的2级Id】,idList【封装要删除的Id】);
        });
    }

3.swagger答疑:

這個是指不顯示 

 4.几个新注解

@Min 验证 Number 和 String 对象是否大等于指定的值

@Max 验证 Number 和 String 对象是否小等于指定的值

@Size(min=, max=) 验证对象(Array,Collection,Map,String)长度是否在给定的范围之内

@Length(min=, max=) 验证字符串长度是否在给定的范围之内

max和min是对你填的“数字”是否大于或小于指定值,这个“数字”可以是number或者string类型。长度限制用length。
如果在long类型上加@size就会出现报错:

No validator could be found for constraint 'javax.validation.constraints.NotEmpty' validating type 'java.lang.Long'. Check configuration for 'roleId', org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree.getExceptionForNullValidator(ConstraintTree.java:116)
javax.validation.UnexpectedTypeException: HV000030: No validator could be found for constraint 'javax.validation.constraints.NotEmpty' validating type 'java.lang.Long'. Check configuration for 'roleId'

5.角色分配:

    //=========================给角色分配菜单=======================就是给中介表加数据
    @Override
    public void saveRolePermissionRealtionShipGuli(String roleId, String[] permissionIds) {
        //roleId角色id
        //permissionId菜单id 数组形式
//一个角色有多个菜单,最终以集合的形式批量添加。
        //1 创建list集合,用于封装添加数据
        List<RolePermission> rolePermissionList = new ArrayList<>();
        //遍历所有菜单数组
        for(String perId : permissionIds) {
            //RolePermission对象
            RolePermission rolePermission = new RolePermission();
            rolePermission.setRoleId(roleId);
            rolePermission.setPermissionId(perId);
            //封装到list集合,一条一条加进去
            rolePermissionList.add(rolePermission);
        }
        //添加到角色菜单关系表,批量添加
        rolePermissionService.saveBatch(rolePermissionList);
    }

6. 数组转集合,集合转数组

数组与集合相互转化_wanlin77的博客-优快云博客_数组转集合的方法

toArrey,aslist 

7.@tableLogic 

注意逻辑删除时候Boolean类型要加这个注解,前端传入不用引号。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值