网站首页 > java教程 正文
现在有一张菜单表 和 一张资源表,表结构如下:
system_menu(id,pid,title,...) //id-菜单ID pid-上级菜单ID title-菜单名称
system_menu_resource(id,menu_id,title,...) //id-资源ID menu_id-菜单ID title资源名称
需求如下:
请删除ID=1000的菜单及其下面的所有子菜单 和 关联的所有资源
是不是有写过类似的案例,请问你首先想到的解决方案是不是通过递归调用来实现业务逻辑呢?
常见的递归写法一
#### Java语法
public void deleteMenuById(Long id) {
List<Long> subMenuIdList = menuDao.querySubMenuIdByPid(id); //查找子菜单ID列表
for(Long subMenuId : subMenuIdList) {
deleteMenuById(subMenuId); //递归调用删除子菜单的数据
}
menuDao.deleteMenuById(id); //删除菜单
resourcesDao.deleteResourceByMenuId(id); //删除资源
}
递归调用删除菜单,数据库操作过于频繁,当然这只是一个菜单表,数据量小,没什么影响。
对于数据库操作过于频繁,你可能已经想到了解决方法:批量删除,请看下面
常见的递归写法二
#### Java语法
public void deleteMenuById(Long id) {
List<Long> idList = new ArrayList(); //要删除的菜单ID列表
querySubMenuId(id, idList); //idList属于地址传递哦
menuDao.deleteMenusById(idList); //批量删除菜单
resourcesDao.deleteResourcesByMenuId(idList); //批量删除资源
}
private void querySubMenuId(Long id, List<Long> idList) {
List<Long> sub = menuDao.querySubMenuIdByPid(id); //查找子菜单
for(Long subid : sub) {
idList.add(subid); //添加到列表中
querySubMenuId(subid); //递归调用查找子菜单
}
}
看到这里,是不是感觉很好了,效率很高了呢,没有什么优化的方案了?
接下来 我们看一下如何去掉递归调用查询数据
推荐的写法
#### Java语法
public void deleteMenuById(Long id) {
List<Long> idList = new ArrayList<>(); //需要删除的菜单ID列表
Queue<Long> queue = new LinkedList<>(); //临时队列
queue.offer(id); //先把最上面的菜单ID放入对列
Long menuId = null;
while((menuId = ids.poll()) != null) { //出队列,没有代表所有子菜单全部查完了
idList.add(menuId); //要删除的菜单ID
queue.addAll(menuDao.querySubMenuIdByPid(menuId)); //查询子菜单ID 并 入对列
}
menuDao.deleteMenusById(idList); //批量删除菜单
resourcesDao.deleteResourcesByMenuId(idList); //批量删除资源
}
有没有发现,我们已经成功的把递归去掉了,结合队列实现了多级菜单删除功能。
小结
可能有人会有疑问,有没有办法把查询子菜单的SQL也优化成:一条SQL可以把菜单下面的所有子菜单全部查询出来,不再循环查询呢?
答案是有的,这篇文章就不介绍了,我们的目标是去掉递归用法,现在已经实现了。后续再单独介绍("进制"级别表示法)。
长路漫漫,每天坚持至少一篇,写的好的话,还请多多宣传多多留言,记的『关注』我哦!
猜你喜欢
- 2024-10-22 「是时候升级Java11了」 JDK11优势和JDK选择
- 2024-10-22 一文读懂关于Java如何找出两个列表之间的新增和删除元素
- 2024-10-22 JAVA 面试高频提问知识点之:SET、LIST 和 MAP 的区别
- 2024-10-22 Java常规操作新增,更新,删除(java常规操作新增,更新,删除什么意思)
- 2024-10-22 JAVA全栈CMS系统Vue无限级分类拖拽增改查批量删除7
- 2024-10-22 「LeetCode」删除字符串中的所有相邻重复项Java题解
- 2024-10-22 sed命令之删除匹配行的详细介绍(sed命令删除指定内容范围)
- 2024-10-22 # Redis 入门到精通(七)-- redis 删除策略
- 2024-10-22 【Java面试题】List如何一边遍历,一边删除?
- 2024-10-22 Redis03——Redis是如何删除你的数据的
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)