这是一个超级简单的实现,未考虑代码执行效率等因素,仅供参考。。。
数据库设计: menu表,顶级菜单parentId默认为-1,同一个顶级菜单下所有菜单的rootId为顶级菜单的id。(若多个系统共用一个表,可增加一列:系统编码,根据系统编码查询指定系统下的所有菜单)
Menu.java
@Data
public class Menu {
private int id;
private String name;
private int parentId;
private int rootId;
private Date createTime;
private List<Menu> childMenus;
}
MenuDao.java
@Mapper
@Repository
public interface MenuDao {
@Select("select id, name, parentId, rootId, createTime " +
"from menu where rootId=#{rootId} order by createTime")
List<Menu> queryByRootId(int rootId);
@Select("select id, name, parentId, rootId, createTime " +
"from menu order by createTime")
List<Menu> queryAll();
}
MenuService.java
public interface MenuService {
Menu queryByRootId(int rootId);
List<Menu> queryAll();
}
MenuServiceImpl.java
@Service
public class MenuServiceImpl implements MenuService {
@Autowired
private MenuDao menuDao;
/**
* 根据rootId查找其下所有菜单,然后递归遍历出子菜单
* @param rootId
* @return
*/
@Override
public Menu queryByRootId(int rootId) {
List<Menu> menus = menuDao.queryByRootId(rootId);
Menu result = null;
for (Menu menu : menus) {
findChildMenu(menus, menu);
if (menu.getParentId() == -1) {
result = menu;
}
}
return result;
}
/**
* 查询所有菜单,然后递归遍历出子菜单
* @return
*/
@Override
public List<Menu> queryAll() {
List<Menu> menus = menuDao.queryAll();
List<Menu> result = new ArrayList<>();
for (Menu menu : menus) {
findChildMenu(menus, menu);
if (menu.getParentId() == -1) {
result.add(menu);
}
}
return result;
}
private void findChildMenu(List<Menu> menus, Menu parentMenu) {
for (Menu menu : menus) {
if (menu.getParentId() == parentMenu.getId()) {
List<Menu> childMenus = parentMenu.getChildMenus();
if (childMenus == null) {
childMenus = new ArrayList<>();
}
if (!childMenus.contains(menu)) {
childMenus.add(menu);
}
parentMenu.setChildMenus(childMenus);
}
}
}
}
MenuController.java
@RestController
@RequestMapping("/")
public class MenuController {
@Autowired
private MenuService menuService;
@GetMapping("/menu/{rootId}")
public Menu query(@PathVariable("rootId") int rootId) {
return menuService.queryByRootId(rootId);
}
@GetMapping("/menu/all")
public List<Menu> queryAll() {
return menuService.queryAll();
}
}
请求 /menu/{rootId},rootId=1, 返回结果:
{
"id": 1,
"name": "设置",
"parentId": -1,
"rootId": 1,
"createTime": "2020-03-14T09:14:35.000+0000",
"childMenus": [
{
"id": 2,
"name": "通用",
"parentId": 1,
"rootId": 1,
"createTime": "2020-03-14T09:15:28.000+0000",
"childMenus": [
{
"id": 4,
"name": "声音",
"parentId": 2,
"rootId": 1,
"createTime": "2020-03-14T09:15:57.000+0000",
"childMenus": null
},
{
"id": 5,
"name": "字体",
"parentId": 2,
"rootId": 1,
"createTime": "2020-03-14T09:16:44.000+0000",
"childMenus": [
{
"id": 6,
"name": "系统字体",
"parentId": 5,
"rootId": 1,
"createTime": "2020-03-14T10:21:17.000+0000",
"childMenus": null
},
{
"id": 7,
"name": "文本字体",
"parentId": 5,
"rootId": 1,
"createTime": "2020-03-14T10:22:18.000+0000",
"childMenus": null
}
]
}
]
},
{
"id": 3,
"name": "隐私",
"parentId": 1,
"rootId": 1,
"createTime": "2020-03-14T09:15:30.000+0000",
"childMenus": null
}
]
}
请求 /menu/all 返回结果:
[
{
"id": 1,
"name": "设置",
"parentId": -1,
"rootId": 1,
"createTime": "2020-03-14T09:14:35.000+0000",
"childMenus": [
{
"id": 2,
"name": "通用",
"parentId": 1,
"rootId": 1,
"createTime": "2020-03-14T09:15:28.000+0000",
"childMenus": [
{
"id": 4,
"name": "声音",
"parentId": 2,
"rootId": 1,
"createTime": "2020-03-14T09:15:57.000+0000",
"childMenus": null
},
{
"id": 5,
"name": "字体",
"parentId": 2,
"rootId": 1,
"createTime": "2020-03-14T09:16:44.000+0000",
"childMenus": [
{
"id": 6,
"name": "系统字体",
"parentId": 5,
"rootId": 1,
"createTime": "2020-03-14T10:21:17.000+0000",
"childMenus": null
},
{
"id": 7,
"name": "文本字体",
"parentId": 5,
"rootId": 1,
"createTime": "2020-03-14T10:22:18.000+0000",
"childMenus": null
}
]
}
]
},
{
"id": 3,
"name": "隐私",
"parentId": 1,
"rootId": 1,
"createTime": "2020-03-14T09:15:30.000+0000",
"childMenus": null
}
]
},
{
"id": 8,
"name": "相册",
"parentId": -1,
"rootId": 8,
"createTime": "2020-03-14T10:23:38.000+0000",
"childMenus": null
},
{
"id": 9,
"name": "表情",
"parentId": -1,
"rootId": 9,
"createTime": "2020-03-14T10:23:58.000+0000",
"childMenus": null
}
]