分类管理模块
功能:
1.增加分类
2.修改分类名字
3.获取当前子分类
4.获取当前分类的所有子分类(递归获取)
controller层实现:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 @RequestMapping(value = "get_category_and_deep_children_category.do", method = RequestMethod.POST) 2 @ResponseBody 3 public ServerResponse getCategoryAndDeepChildrenCategory(HttpServletRequest request, @RequestParam(value = "categoryId", defaultValue = "0") Integer categoryId) { 4 // User user = (User) session.getAttribute(Const.CURRENT_USER); 5 6 String loginToken = CookieUtil.readLoginToken(request); 7 if(StringUtils.isEmpty(loginToken)) { 8 return ServerResponse.createByErrorMessage("用户未登录,无法获取当前用户的信息"); 9 } 10 String userJsonStr = RedisShardedPoolUtil.get(loginToken); 11 User user = JsonUtil.string2Obj(userJsonStr, User.class); 12 13 if(user == null) { 14 return ServerResponse.createByErrorCodeMessage(ResponseCode.NEED_LOGIN.getCode(), "用户未登录,请登录"); 15 } 16 if(iUserService.checkAdminRole(user).isSuccess()) { 17 //查询当前结点的id和递归子结点的id 18 return iCategoryService.selectCategoryAndChildrenById(categoryId); 19 } 20 else { 21 return ServerResponse.createByErrorMessage("无权限操作,需要管理员权限"); 22 } 23 //全部通过拦截器验证是否登录以及权限 24 //return iCategoryService.selectCategoryAndChildrenById(categoryId); 25 }
service层实现:
根据传入的分类id,递归查询其所有的子分类,根据每一层查询出来的所有子分类节点,再对这些节点进行深入的递归调用,相当于DFS,对于每次查出来的子分类节点,将其加入set集合中,将set集合返回即可。在对外开放的public方法中,将set集合转为list返回给前端进行显示。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 public ServerResponse<List<Integer>> selectCategoryAndChildrenById(Integer categoryId) { 2 Set<Category> categorySet = Sets.newHashSet(); 3 //调用递归函数,将set初始化放入参数中 4 findChildrenCategory(categorySet, categoryId); 5 //创建返回list 6 List<Integer> categoryIdList = Lists.newArrayList(); 7 //如果id不为空,说明有返回结点,则将递归查到的所有id都加入到list中然后返回 8 if(categoryId != null) { 9 for(Category categoryItem : categorySet) { 10 categoryIdList.add(categoryItem.getId()); 11 } 12 } 13 return ServerResponse.createBySuccess(categoryIdList); 14 } 15 //递归算法,算出子结点 16 //set集合不允许重复值 17 private Set<Category> findChildrenCategory(Set<Category> categorySet, Integer categoryId) { 18 //根据id查category对象 19 Category category = categoryMapper.selectByPrimaryKey(categoryId); 20 if(category != null) { 21 //将查找出来的category对象加入set集合中 22 categorySet.add(category); 23 } 24 //查找子结点,递归算法一定要有一个退出的条件 25 List<Category> categoryList = categoryMapper.selectCategoryChildrenByParentId(categoryId); 26 for(Category categoryItem : categoryList) { 27 //递归调用 28 findChildrenCategory(categorySet, categoryItem.getId()); 29 } 30 //将set集合返回 31 return categorySet; 32 }
掌握:
1.如何设计及封装无限层级的树状数据结构
设置parent_id字段,实现每一个分类节点都有父节点,也就实现了树状结构。
2.递归算法的设计思想
3.如何处理复杂对象的排重
使用set进行排重,需要重写加入set集合的对象的hashCode()和equals()方法。
4.重写hashCode和equals的注意思想
需要同时重写hashCode()和equals()方法。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 //重写equals和hashCode方法来进行排重,并且保证两者的判断因子是一样的,例如这里都利用id判断 2 //equals和hashCode关系:如果两个对象相同,即用equlas比较返回true,则他们的hashCode值一定要相同 3 //如果两个对象的hashCode相同,他们并不一定相同,即hashCode相同,用equlas比较也可能返回false,为什么? 4 //因为hashCode只是取了id的hashCode作为一个因子,而我们的equals中可以把其他属性放入综合判定是否相同 5 @Override 6 public boolean equals(Object o) { 7 if (this == o) return true; 8 if (o == null || getClass() != o.getClass()) return false; 9 10 Category category = (Category) o; 11 12 return !(id != null ? !id.equals(category.id) : category.id != null); 13 14 } 15 16 @Override 17 public int hashCode() { 18 return id != null ? id.hashCode() : 0; 19 }