面试:分类模块要点
1、递归算法
2、复杂对象排重
3、无限层级树结构设计
一、添加分类
1、判断用户是否登录
2、判断用户是否是管理员
3、如果是管理员则根据分类名和父类id添加分类节点
具体流程:
Controller:
//添加分类
@RequestMapping("add_category.do")
@ResponseBody
public ServerResponse addCategory(HttpSession session, String categoryName, @RequestParam(value = "parentId",defaultValue = "0") int parentId){ //默认父节点为0
User user = (User)session.getAttribute(Const.CURRENT_USER);
if(user == null)
return ServerResponse.createByErrorCodeMessage(ResponseCode.NEED_LOGIN.getCode(),"用户未登录,请登录");
if(iUserService.checkAdminRole(user).isSuccess()) //校验一下是否是管理员
return iCategoryService.addCategory(categoryName,parentId); //添加分类
else
return ServerResponse.createByErrorMessage("无权限操作,需要管理员权限");
}
Service:
public ServerResponse addCategory(String categoryName,Integer parentId){
//它的父分类不能为空,其本身分类名也不能为空
if(parentId == null || StringUtils.isBlank(categoryName))
return ServerResponse.createByErrorMessage("添加品类参数错误");
Category category = new Category(); //创建分类
category.setName(categoryName);
category.setParentId(parentId);
category.setStatus(true); //这个分类是可用的
int rowCount = categoryMapper.insert(category); //添加分类
if(rowCount > 0)
return ServerResponse.createBySuccess("添加品类成功");
return ServerResponse.createByErrorMessage("添加品类失败");
}
二、修改分类
1、判断用户是否登录
2、判断用户是否是管理员
3、根据分类id修改分类名
具体流程:
Controller:
//修改分类名字
@RequestMapping("set_category_name.do")
@ResponseBody
public ServerResponse setCategoryName(HttpSession session,Integer categoryId,String categoryName){
User user = (User)session.getAttribute(Const.CURRENT_USER);
if(user == null){
return ServerResponse.createByErrorCodeMessage(ResponseCode.NEED_LOGIN.getCode(),"用户未登录,请登录");
if(iUserService.checkAdminRole(user).isSuccess()){
return iCategoryService.updateCategoryName(categoryId,categoryName); //更新categoryName
}else{
return ServerResponse.createByErrorMessage("无权限操作,需要管理员权限");
}
}
三、获取平级节点
1、判断用户是否登录
2、判断用户是否是管理员
3、根据id查询评级节点
具体流程:
Controller:
@RequestMapping("get_category.do")
@ResponseBody
public ServerResponse getChildrenParallelCategory(HttpSession session,@RequestParam(value = "categoryId" ,defaultValue = "0") Integer categoryId){
User user = (User)session.getAttribute(Const.CURRENT_USER);
if(user == null){
return ServerResponse.createByErrorCodeMessage(ResponseCode.NEED_LOGIN.getCode(),"用户未登录,请登录");
}
if(iUserService.checkAdminRole(user).isSuccess()){
//查询子节点的category信息,并且不递归,保持平级
return iCategoryService.getChildrenParallelCategory(categoryId);
}else{
return ServerResponse.createByErrorMessage("无权限操作,需要管理员权限");
}
}
Service:
public ServerResponse> getChildrenParallelCategory(Integer categoryId){
List categoryList = categoryMapper.selectCategoryChildrenByParentId(categoryId);
if(CollectionUtils.isEmpty(categoryList))
logger.info("未找到当前分类的子分类");
return ServerResponse.createBySuccess(categoryList);
}
这里附上CollectionUtils的使用方法:Java基础系列(二十五)CollectionUtils
Mapper接口:
public interface CategoryMapper {
List selectCategoryChildrenByParentId(Integer parentId);
}
Mapper.xml:
select
from mmall_category
where parent_id = #{parentId}
四、获取平级节点及其所有子节点
1、判断用户是否登录
2、判断用户是否是管理员
3、使用set集合保存Category对象
4、重写category对象的hashcode和equals方法
5、根据父类id使用递归算法算出子节点
具体流程:
Controller:
//递归查询该节点下的所有子节点
@RequestMapping("get_deep_category.do")
@ResponseBody
public ServerResponse getCategoryAndDeepChildrenCategory(HttpSession session,@RequestParam(value = "categoryId" ,defaultValue = "0") Integer categoryId){
User user = (User)session.getAttribute(Const.CURRENT_USER);
if(user == null)
return ServerResponse.createByErrorCodeMessage(ResponseCode.NEED_LOGIN.getCode(),"用户未登录,请登录");
if(iUserService.checkAdminRole(user).isSuccess())
//查询当前节点的id和递归子节点的id 0->10000->100000
return iCategoryService.selectCategoryAndChildrenById(categoryId);
else
return ServerResponse.createByErrorMessage("无权限操作,需要管理员权限");
}
Service:
//递归查询本节点的id及孩子节点的id
public ServerResponse> selectCategoryAndChildrenById(Integer categoryId){
Set categorySet = Sets.newHashSet();
findChildCategory(categorySet,categoryId);
List categoryIdList = Lists.newArrayList();
if(categoryId != null){
for(Category categoryItem : categorySet){
categoryIdList.add(categoryItem.getId());
}
}
return ServerResponse.createBySuccess(categoryIdList);
}
//递归算法,算出子节点
private Set findChildCategory(Set categorySet ,Integer categoryId){
Category category = categoryMapper.selectByPrimaryKey(categoryId);
if(category != null)
categorySet.add(category);
//查找子节点,递归算法一定要有一个退出的条件
List categoryList = categoryMapper.selectCategoryChildrenByParentId(categoryId);
for(Category categoryItem : categoryList){
findChildCategory(categorySet,categoryItem.getId());
}
return categorySet;
}
五、递归算法和无限层级树结构设计
无限层级树结构设计:
给每条数据加个 parent_id字段,通过parent_id来建立数据之间的父子(层级)关系,parent_id为0是根节点。
例如:
BCD分别是空调类、电视机类、智能家居类,而EFGHIJ是具体类如EFG是海尔空调、格力空调、TCL空调,而他们下面也有不同型号的空调,所以就可以无限叠加下去
递归算法设计:
//递归算法,算出子节点
//只要该节点不为空就将其添加到Set集合中
private Set findChildCategory(Set categorySet ,Integer categoryId){
Category category = categoryMapper.selectByPrimaryKey(categoryId);
if(category != null)
categorySet.add(category);
//查找子节点,递归算法一定要有一个退出的条件
List categoryList = categoryMapper.selectCategoryChildrenByParentId(categoryId);
for(Category categoryItem : categoryList){
findChildCategory(categorySet,categoryItem.getId());
}
return categorySet;
}
六、复杂对象排重
使用hashSet并重写其hashcode和equal。这样递归得到的分类节点中就没有重复的。
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Category category = (Category) o;
return !(id != null ? !id.equals(category.id) : category.id != null);
}
@Override
public int hashCode() {
return id != null ? id.hashCode() : 0;
}
Java面试的完整博客目录如下:Java笔试面试目录