在后台管理系统开发中,菜单管理是一个核心功能,而删除菜单作为其中的重要操作,需要考虑数据完整性、关联关系处理和操作安全性。本文将详细介绍 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 菜单删除内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论