Spring Boot 菜单删除实现代码与事务管理

 更新时间:2025年08月13日 10:19:51   作者:小白的代码日记  
本文将详细介绍Spring Boot环境下菜单删除功能的实现逻辑,包括关联数据处理、事务控制和异常处理等关键环节,强调需处理多级嵌套、角色关联及数据一致性,感兴趣的朋友跟随小编一起看看吧

在后台管理系统开发中,菜单管理是一个核心功能,而删除菜单作为其中的重要操作,需要考虑数据完整性、关联关系处理和操作安全性。本文将详细介绍 Spring Boot 环境下菜单删除功能的实现逻辑,包括关联数据处理、事务控制和异常处理等关键环节。

菜单删除的业务逻辑分析

菜单删除并非简单地删除一条记录,需要考虑以下几点:

  • 菜单可能存在多级嵌套关系(父菜单与子菜单)
  • 菜单与角色存在多对多关联(通过中间表 role_menu)
  • 操作需要具备原子性(要么全部成功,要么全部失败)

因此,完整的菜单删除逻辑应该是:先删除关联数据,再删除子菜单,最后删除父菜单本身,并通过事务保证整个过程的完整性。

实现代码与步骤解析

1. 控制器层(MenuController)

首先定义删除接口,接收菜单 ID 并添加事务注解:

@RestController
@RequestMapping("/menu")
public class MenuController {
    @Autowired
    private MenuService menuService;
    @Autowired
    private RoleMenuMapper roleMenuMapper;
    /**
     * 删除菜单
     * @param id 菜单ID
     * @return 操作结果
     */
    @DeleteMapping("/del/{id}")
    @Transactional  // 事务注解,确保操作原子性
    public Result deleteMenu(@PathVariable Integer id) {
        try {
            // 1. 查询所有子菜单
            QueryWrapper<MenuEntity> subMenuQuery = new QueryWrapper<>();
            subMenuQuery.eq("parent_id", id);
            List<MenuEntity> subMenus = menuService.list(subMenuQuery);
            // 2. 先删除子菜单与角色的关联关系
            if (!subMenus.isEmpty()) {
                for (MenuEntity subMenu : subMenus) {
                    QueryWrapper<RoleMenuEntity> roleMenuQuery = new QueryWrapper<>();
                    roleMenuQuery.eq("menu_id", subMenu.getMenuId());
                    roleMenuMapper.delete(roleMenuQuery);
                }
                // 3. 删除子菜单
                menuService.remove(subMenuQuery);
            }
            // 4. 删除当前菜单与角色的关联关系
            QueryWrapper<RoleMenuEntity> parentRoleMenuQuery = new QueryWrapper<>();
            parentRoleMenuQuery.eq("menu_id", id);
            roleMenuMapper.delete(parentRoleMenuQuery);
            // 5. 删除当前菜单
            boolean isDeleted = menuService.removeById(id);
            if (isDeleted) {
                return Result.success("菜单删除成功");
            } else {
                return Result.error("菜单不存在或已被删除");
            }
        } catch (Exception e) {
            // 抛出运行时异常,触发事务回滚
            throw new RuntimeException("删除菜单失败:" + e.getMessage());
        }
    }
}

2. 关键步骤解析

步骤 1:查询子菜单

通过 parent_id 查询当前菜单的所有子菜单,为后续级联删除做准备:

QueryWrapper<MenuEntity> subMenuQuery = new QueryWrapper<>();
subMenuQuery.eq("parent_id", id);
List<MenuEntity> subMenus = menuService.list(subMenuQuery);

步骤 2:删除子菜单与角色的关联关系

由于菜单与角色通过中间表 role_menu 关联,需要先删除这些关联数据,避免外键约束错误:

for (MenuEntity subMenu : subMenus) {
    QueryWrapper<RoleMenuEntity> roleMenuQuery = new QueryWrapper<>();
    roleMenuQuery.eq("menu_id", subMenu.getMenuId());
    roleMenuMapper.delete(roleMenuQuery);
}

步骤 3:删除子菜单

在删除关联数据后,批量删除所有子菜单:

menuService.remove(subMenuQuery);

步骤 4:删除当前菜单与角色的关联关系

同样需要解除当前菜单与角色的关联:

QueryWrapper<RoleMenuEntity> parentRoleMenuQuery = new QueryWrapper<>();
parentRoleMenuQuery.eq("menu_id", id);
roleMenuMapper.delete(parentRoleMenuQuery);

步骤 5:删除当前菜单

最后删除主菜单记录:

menuService.removeById(id);

事务管理与异常处理

  • 事务保证:通过@Transactional注解,确保整个删除过程的原子性。如果任何步骤失败,所有操作都会回滚,避免数据不一致。
  • 异常处理
    • 使用 try-catch 块捕获可能的异常
    • 抛出RuntimeException触发事务回滚(符合 Spring 事务默认回滚规则)
    • 提供清晰的错误信息,便于问题排查
  • 删除顺序原则
    • 先删关联数据,再删主数据
    • 先删子菜单,再删父菜单
    • 遵循 "从外向内、从下到上" 的删除顺序,避免外键约束冲突

到此这篇关于Spring Boot 菜单删除功能的实现与事务管理的文章就介绍到这了,更多相关Spring Boot 菜单删除内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • JAVA加密算法数字签名实现原理详解

    JAVA加密算法数字签名实现原理详解

    这篇文章主要介绍了JAVA加密算法数字签名实现原理详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-10-10
  • Java整数和字符串相互转化实例详解

    Java整数和字符串相互转化实例详解

    这篇文章主要介绍了Java整数和字符串相互转化实例详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-02-02
  • Java中Collection和Collections的区别

    Java中Collection和Collections的区别

    Collection是一个集合接口,集合类的顶级接口,Collections是一个包装类,本文主要介绍了Java中Collection和Collections的区别,具有一定的参考价值,感兴趣的可以了解一下
    2024-04-04
  • Java内部类的继承(全)

    Java内部类的继承(全)

    这篇文章主要介绍了Java内部类的继承,大家都知道JAVA内部类的构造器必须连接指向其外围类对象的引用,所以在继承内部类的时候,需要在导出类的构造器中手动加入对基类构造器的调用,需要的朋友可以参考下
    2015-07-07
  • Spring Boot整合邮箱发送邮件实例

    Spring Boot整合邮箱发送邮件实例

    大家好,本篇文章主要讲的是Spring Boot整合邮箱发送邮件实例,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下
    2022-02-02
  • java读取txt文件并输出结果

    java读取txt文件并输出结果

    这篇文章主要介绍了java读取txt文件并输出结果,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-11-11
  • 解决jackson反序列化失败InvalidFormatException:Can not deserialize value of type java.util.Date

    解决jackson反序列化失败InvalidFormatException:Can not dese

    这篇文章主要介绍了解决jackson反序列化失败InvalidFormatException:Can not deserialize value of type java.util.Date问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-12-12
  • Java转换流(InputStreamReader/OutputStreamWriter)的使用

    Java转换流(InputStreamReader/OutputStreamWriter)的使用

    本文主要介绍了Java转换流(InputStreamReader/OutputStreamWriter)的使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-01-01
  • MybatisPlus如何自动生成映射文件

    MybatisPlus如何自动生成映射文件

    这篇文章主要介绍了MybatisPlus如何自动生成映射文件,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-01-01
  • Spring MVC项目中log4J和AOP使用详解

    Spring MVC项目中log4J和AOP使用详解

    项目日志记录是项目开发、运营必不可少的内容,有了它可以对系统有整体的把控,出现任何问题都有踪迹可寻。下面这篇文章主要给大家介绍了关于Spring MVC项目中log4J和AOP使用的相关资料,需要的朋友可以参考下。
    2017-12-12

最新评论