使用java实现一个多级菜单树结构
先上数据库ps_pid
字段很重要,是父级菜单的id
Menu类
Menu类要新增一个字段,用来存放子菜单
/**
* 子菜单列表
*/
private List<Menu> children;
用mybatis实现
生成菜单树第一种方式可以利用mybatis
的collection
查询实现
<collection property="children" ofType="com.example.springbootvue.entity.Menu"
column="ps_id" select="findMenuByParentId"/>
column="ps_id"
表示传到findMenuByParentId
这个方法中去的参数,是父IDmybatis
会再进行一次查询,把ps_pid=ps_id
的Menu
回添到children
列表中,自动递归
不过这样会导致mybatis N+1问题
官方建议不使用这种写法
使用java算法实现
最开始获取全部菜单我使用的mybatis
实现生成菜单树,后来写用户权限管理模块的时候,用户的权限不再是所有菜单,而是部分菜单,使用mybatis还没想到解决办法,手动狗头,
然后看了一个大佬写的java生成树代码,真的太妙了,先把获取全部菜单,然后再对菜单进行装配,生成树形结构,话不多说,上代码
//获取菜单树
public List<Menu> getMenuList() {
//获取所有菜单
List<Menu> menuList = menuMapper.getMenuList();
//返回的菜单树列表
List<Menu> menuTree = new ArrayList<>();
// 先找到所有的一级菜单,放入菜单树列表中
for (Menu menu : menuList) {
if (menu.getPsLevel().equals("0")) {
menuTree.add(menu);
}
}
//遍历一级菜单,开始查找子菜单
for (Menu menu : menuTree) {
menu.setChildren(getChildren(menu.getPsId(),menuList));
}
return menuList;
}
private List<Menu> getChildren(Short psId, List<Menu> menuList) {
// 查找二级子菜单
List<Menu> childList = new ArrayList<>();
for (Menu menu : menuList) {
if (menu.getPsPid().equals(psId)) {
childList.add(menu);
}
}
//递归查找查找二级菜单的子菜单
for (Menu menu : childList) {
menu.setChildren(getChildren(menu.getPsId(),menuList));
}
return childList;
}
这样会导致很多重复操作,如果使用java的stream进行过滤性能会更好,等有时间了再更一下