功能:

1.增加分类

2.修改分类名字

3.获取当前子分类

4.获取当前分类的所有子分类(递归获取)

controller层实现:

 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     }

View Code

service层实现:

根据传入的分类id,递归查询其所有的子分类,根据每一层查询出来的所有子分类节点,再对这些节点进行深入的递归调用,相当于DFS,对于每次查出来的子分类节点,将其加入set集合中,将set集合返回即可。在对外开放的public方法中,将set集合转为list返回给前端进行显示。

 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     }

View Code

掌握:

1.如何设计及封装无限层级的树状数据结构

设置parent_id字段,实现每一个分类节点都有父节点,也就实现了树状结构。

2.递归算法的设计思想

3.如何处理复杂对象的排重

使用set进行排重,需要重写加入set集合的对象的hashCode()和equals()方法。

4.重写hashCode和equals的注意思想

需要同时重写hashCode()和equals()方法。

 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     }

View Code