Java转树形结构案例(菜单管理)
2018-05-31 本文已影响0人
LeonardoEzio
实体类(一) 映射数据库
@Entity
@Table
public class SysMenu {
private Long id;
/** 菜单名称 */
@NotBlank(message="菜单名称不能为空")
private String name;
/** 菜单URL */
@NotBlank(message="菜单url不能为空")
private String url;
/** 父菜单ID */
private Long parentId;
/** 是否可见(0:否,1:是) */
private Integer displayFlag;
}
实体类(二) 转换结构使用
public class SysMenuVO {
private Long Id;
/** 菜单名称 */
private String name;
/** 菜单URL */
private String url;
/** 父菜单ID */
private Long parentId;
/** 是否可见(0:否,1:是) */
private Integer displayFlag;
private List<SysMenuVO> childMenus;
}
Controller层
@Controller
@RequestMapping("sys/menu")
public class SystemMenuController extends BaseController {
private Logger logger = LoggerFactory.getLogger(ContractArchiveController.class);
@Autowired
private SystemMenuService systemMenuService;
@RequestMapping("findAll")
@ResponseBody
public ResultBean<List<SysMenuVO>> findAllMenu(){
List<SysMenuVO> allMenu = systemMenuService.findAllMenu();
ResultBean<List<SysMenuVO>> menuResult = new ResultBean<>(allMenu);
menuResult.setCode(ResultBean.SUCCESS);
menuResult.setMessages("all menu return successful");
return menuResult;
}
}
Service层
@Service
public class SystemMenuService {
@Autowired
private SystemMenuRepository systemMenuRepository;
//获取所有菜单
public List<SysMenuVO> findAllMenu(){
return this.getMenusFromDb();
}
private List<SysMenuVO> getMenusFromDb(){
SysMenu searchStandard = new SysMenu();
//这里采用SpringDataJpa的Specification查询,不懂的可以百度
Specification<SysMenu> specification = getSpecification(searchStandard);
//按父级菜单的id排序获取查询结果集
Sort orders = new Sort(Sort.Direction.ASC,"parentId");
List<SysMenu> resultMenu =(List<SysMenu>)systemMenuRepository.findAll(specification,orders);
//获取树形结构的结果
List<SysMenuVO> menuTree = genMenuTree(resultMenu);
return menuTree;
}
private Specification<SysMenu> getSpecification(SysMenu sysMenu){
Specification<SysMenu> specification = new Specification<SysMenu>() {
@Override
public Predicate toPredicate(Root<SysMenu> root, CriteriaQuery<?> cq, CriteriaBuilder cb) {
List<Predicate> predicates = new ArrayList<Predicate>();
//只获取没有删除的菜单
predicates.add(cb.equal(root.<String>get("delFlag"), Constants.DEL_FLAG_ZERO));
if(null != sysMenu.getParentId()) {
predicates.add(cb.equal(root.<Long>get("parentId"), sysMenu.getParentId()));
}
return cq.where(predicates.toArray(new Predicate[predicates.size()])).getRestriction();
}
};
return specification;
}
private List<SysMenuVO> genMenuTree(List<SysMenu> sysMenus) {
//将数据转成树形结构
Map<Long, List<SysMenuVO>> menuMap = new HashMap<>();
for(SysMenu menu : sysMenus) {
Long parentId = menu.getParentId();
List<SysMenuVO> tmpList = menuMap.get(parentId) == null ? new ArrayList<SysMenuVO>() : menuMap.get(parentId);
SysMenuVO vo = new SysMenuVO();
BeanUtils.copyProperties(menu, vo);
tmpList.add(vo);
menuMap.put(parentId, tmpList);
}
//设置一个根节点
SysMenuVO vo = new SysMenuVO();
vo.setId(Constants.ROOT_MENU_PARENT_ID);
this.setMenuChidren(vo, menuMap);
return vo.getChildMenus();
}
private void setMenuChidren(SysMenuVO sysMenuVO, Map<Long,List<SysMenuVO>> menuMap) {
//获取根节点下面子菜单集合
List<SysMenuVO> childMenus = menuMap.get(sysMenuVO.getId());
if(CollectionUtils.isNotEmpty(childMenus)) {
//将子菜单集合set进根菜单
sysMenuVO.setChildMenus(childMenus);
for(SysMenuVO vo : childMenus) {
//设置每一个子菜单下的子菜单集合
setMenuChidren(vo, menuMap);
}
}
}
}
注:
本例使用SpringDataJpa 和 Hibernate 仅供自己学习使用