【实战】6-2 分类管理开发

来源:互联网 发布:上海 风情 知乎 编辑:程序博客网 时间:2024/06/05 03:44

前言

商品分类模块给它设计的接口暂时不多,这一章节也比较简单,除了一个递归获取所有子节点的接口外~
接下来就一个一个文件的放出来,大家直接参考和看代码中的注释就好了。

controller设计

这里在controller/backend包下创建CategoryManageController.java,专门用来控制对商品分类的操作。
功能大部分还是在service中实现的,这里主要是把session中的相关信息拿出来,并做一些简单的判断,如是否登录,是否是管理员等。
注意使用了一个新的注解@RequestParam(value = “parentId”,defaultValue = “0”)可以实现不传参数情况下的默认参数(感觉这些注解实现了很强大的功能,有时间要好好了解一下具体的实现原理)。

package top.winxblast.happymall.controller.backend;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import org.springframework.web.bind.annotation.RequestParam;import org.springframework.web.bind.annotation.ResponseBody;import top.winxblast.happymall.common.Const;import top.winxblast.happymall.common.ResponseCode;import top.winxblast.happymall.common.ServerResponse;import top.winxblast.happymall.pojo.User;import top.winxblast.happymall.service.CategoryService;import top.winxblast.happymall.service.UserService;import javax.servlet.http.HttpSession;/** * 目录管理模块 * * @author winxblast * @create 2017/10/28 **/@Controller@RequestMapping(value = "/manage/category")public class CategoryManageController {    @Autowired    private UserService userService;    @Autowired    private CategoryService categoryService;    /**     * 添加商品类别     * 添加这个注解@RequestParam(value = "parentId",defaultValue = "0")主要是为了没有传这个参数时有个默认值。     * @param session 通过session验证用户是否已登录以及是否为管理员     * @param categoryName     * @param parentId     * @return     */    @RequestMapping(value = "add_category.do", method = RequestMethod.GET)    @ResponseBody    public ServerResponse<String> addCategory(HttpSession session, String categoryName, @RequestParam(value = "parentId",defaultValue = "0") int parentId) {        User user = (User)session.getAttribute(Const.CURRENT_USER);        if(user == null) {            return ServerResponse.createByErrorCodeMessage(ResponseCode.NEED_LOGIN.getCode(), "用户未登录,请登录");        }        //校验是否为管理员,功能放到service中        if(userService.checkAdminRole(user).isSuccess()) {            //是管理员            //增加处理分类的逻辑            return categoryService.addCategory(categoryName, parentId);        } else {            return ServerResponse.createByErrorMessage("无权限,需要管理员权限");        }    }    /**     * 修改品类名称     * @param session     * @param categoryId     * @param categoryName     * @return     */    @RequestMapping(value = "set_category_name.do", method = RequestMethod.GET)    @ResponseBody    public ServerResponse<String> 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(), "用户未登录,请登录");        }        //校验是否为管理员,功能放到service中        if(userService.checkAdminRole(user).isSuccess()) {            //是管理员            //更新categoryName            return categoryService.updateCategoryName(categoryId, categoryName);        }else {            return ServerResponse.createByErrorMessage("无权限,需要管理员权限");        }    }    /**     * 通过父类id获取下一级子分类     * @param session     * @param categoryId 不传参数默认为0     * @return     */    @RequestMapping(value = "get_category.do", method = RequestMethod.GET)    @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(userService.checkAdminRole(user).isSuccess()) {            //查询子节点的category信息,并且不递归,只查询下一级            return categoryService.getChildrenParallelCategory(categoryId);        } else {            return ServerResponse.createByErrorMessage("无权限,需要管理员权限");        }    }    /**     * 通过递归查询该分类下所有子分类     * 这个方法的名字取的我也是醉了···最讨厌取名字了,这里老师取名感觉也是随意     * @param session     * @param categoryId 不传参数默认为0     * @return     */    @RequestMapping(value = "get_deep_category.do", method = RequestMethod.GET)    @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(userService.checkAdminRole(user).isSuccess()) {            //查询当前节点及递归子节点的id            return categoryService.selectCategoryAndChildrenById(categoryId);        } else {            return ServerResponse.createByErrorMessage("无权限,需要管理员权限");        }    }}

service设计

先给出接口的定义把CategoryService。后来我按照阿里巴巴Java规约的一些习惯把接口命名前面的大写“I”去掉了,直接使用xxService,然后在实现类后面加上Impl。

package top.winxblast.happymall.service;import top.winxblast.happymall.common.ServerResponse;import top.winxblast.happymall.pojo.Category;import java.util.List;/** * 分类操作模块接口 * * @author winxblast * @create 2017/10/28 **/public interface CategoryService {    ServerResponse<String> addCategory(String categoryName, Integer parentId);    ServerResponse<String> updateCategoryName(Integer categoryId, String categoryName);    ServerResponse<List<Category>> getChildrenParallelCategory(Integer categoryId);    ServerResponse selectCategoryAndChildrenById(Integer categoryId);}

然后是接口的实现类。这里混用了google的guava和Apache的commons,网上讨论也比较多,暂时还没有精力去分辨那个好,这里就先按老师写的混用着。
至于以后工作中那就看同事用什么就用什么啦

package top.winxblast.happymall.service.impl;import com.google.common.collect.Lists;import com.google.common.collect.Sets;import org.apache.commons.collections.CollectionUtils;import org.apache.commons.lang3.StringUtils;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import top.winxblast.happymall.common.ServerResponse;import top.winxblast.happymall.dao.CategoryMapper;import top.winxblast.happymall.pojo.Category;import top.winxblast.happymall.service.CategoryService;import java.util.List;import java.util.Set;/** * 分类模块接口实现类 * * @author winxblast * @create 2017/10/28 **/@Service("categoryService")public class CategoryServiceImpl implements CategoryService {    private Logger logger = LoggerFactory.getLogger(CategoryServiceImpl.class);    @Autowired    private CategoryMapper categoryMapper;    /**     * 添加品类     * @param categoryName 品类名称     * @param parentId 父品类id,SpringMVC中默认使用0,如果没有传入     * @return     */    @Override    public ServerResponse<String> 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.createBySuccessMessage("添加品类成功");        }        return ServerResponse.createByErrorMessage("添加品类失败");    }    /**     * 修改品类名字     * @param categoryId     * @param categoryName     * @return     */    @Override    public ServerResponse<String> updateCategoryName(Integer categoryId, String categoryName) {        if(categoryId == null || StringUtils.isBlank(categoryName)) {            return ServerResponse.createByErrorMessage("更新品类参数错误");        }        Category category = new Category();        category.setId(categoryId);        category.setName(categoryName);        int rowCount = categoryMapper.updateByPrimaryKeySelective(category);        if(rowCount > 0) {            return ServerResponse.createBySuccessMessage("更改品类名字成功");        }        return ServerResponse.createByErrorMessage("更改品类名字失败");    }    /**     * 仅获取下一级分类     * @param categoryId     * @return     */    @Override    public ServerResponse<List<Category>> getChildrenParallelCategory(Integer categoryId) {        List<Category> categoryList = categoryMapper.selectCategoryChildrenByParentId(categoryId);        if(CollectionUtils.isEmpty(categoryList)) {            //这里没有子分类为什么打印日志比较好呢,应该可以有其他处理方法,这里按照老师的讲解来            logger.info("未找到当前分类的子分类");        }        return ServerResponse.createBySuccess(categoryList);    }    /**     * 递归查询本节点id和孩子节点id     * 和下面一个private方法联合使用     * @param categoryId     * @return     */    @Override    public ServerResponse selectCategoryAndChildrenById(Integer categoryId) {        //这个跟我平时不一样,用的谷歌的一个包来初始化,里面也有很多方便的工具        Set<Category> categorySet = Sets.newHashSet();        findChildCatgory(categorySet,categoryId);        //同样是谷歌guava里的方法        List<Integer> categoryIdList = Lists.newArrayList();        if(categoryId != null) {            for (Category categoryItem : categorySet) {                categoryIdList.add(categoryItem.getId());            }        }        return ServerResponse.createBySuccess(categoryIdList);    }    /**     * 这里要重写Category的hashcode和equals方法     * 递归算法算出子节点     */    private Set<Category> findChildCatgory(Set<Category> categorySet, Integer categoryId) {        Category category = categoryMapper.selectByPrimaryKey(categoryId);        if(category != null) {            categorySet.add(category);        }        //查找子节点,递归算法一定要有停止条件        List<Category> categoryList = categoryMapper.selectCategoryChildrenByParentId(categoryId);        //由于mybatis的设计,如果没有查询结果,也不会返回null,所以下面不用进行null判断        for (Category categoryItem : categoryList) {            findChildCatgory(categorySet, categoryItem.getId());        }        return categorySet;    }}

注意这里重写了category的hashcode和equals方法,因为要把按我们想要的方式放进hashset中。这两个方法的重写直接使用idea提供的方法就可以了。

dao层

对于数据库的操作,在mybatis generator的基础上,自己就添加了一个方法,以下为相关接口及xml配置内容,我自己添加的内容在两个文件的最后部分。

CategoryMapper.java

package top.winxblast.happymall.dao;import top.winxblast.happymall.pojo.Category;import java.util.List;public interface CategoryMapper {    /**     * This method was generated by MyBatis Generator.     * This method corresponds to the database table happymall_category     *     * @mbggenerated Sun Oct 08 14:03:47 CST 2017     */    int deleteByPrimaryKey(Integer id);    /**     * This method was generated by MyBatis Generator.     * This method corresponds to the database table happymall_category     *     * @mbggenerated Sun Oct 08 14:03:47 CST 2017     */    int insert(Category record);    /**     * This method was generated by MyBatis Generator.     * This method corresponds to the database table happymall_category     *     * @mbggenerated Sun Oct 08 14:03:47 CST 2017     */    int insertSelective(Category record);    /**     * This method was generated by MyBatis Generator.     * This method corresponds to the database table happymall_category     *     * @mbggenerated Sun Oct 08 14:03:47 CST 2017     */    Category selectByPrimaryKey(Integer id);    /**     * This method was generated by MyBatis Generator.     * This method corresponds to the database table happymall_category     *     * @mbggenerated Sun Oct 08 14:03:47 CST 2017     */    int updateByPrimaryKeySelective(Category record);    /**     * This method was generated by MyBatis Generator.     * This method corresponds to the database table happymall_category     *     * @mbggenerated Sun Oct 08 14:03:47 CST 2017     */    int updateByPrimaryKey(Category record);    /**     * 通过父类Id查看下一级子分类的情况     * @param parentId     * @return     */    List<Category> selectCategoryChildrenByParentId(Integer parentId);}

CategoryMapper.xml大部分都是自动生成的,自己写的部分也没有特别大的难度。

<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" ><mapper namespace="top.winxblast.happymall.dao.CategoryMapper" >  <resultMap id="BaseResultMap" type="top.winxblast.happymall.pojo.Category" >    <!--      WARNING - @mbggenerated      This element is automatically generated by MyBatis Generator, do not modify.      This element was generated on Sun Oct 08 14:03:47 CST 2017.    -->    <constructor >      <idArg column="id" jdbcType="INTEGER" javaType="java.lang.Integer" />      <arg column="parent_id" jdbcType="INTEGER" javaType="java.lang.Integer" />      <arg column="name" jdbcType="VARCHAR" javaType="java.lang.String" />      <arg column="status" jdbcType="BIT" javaType="java.lang.Boolean" />      <arg column="sort_order" jdbcType="INTEGER" javaType="java.lang.Integer" />      <arg column="create_time" jdbcType="TIMESTAMP" javaType="java.util.Date" />      <arg column="update_time" jdbcType="TIMESTAMP" javaType="java.util.Date" />    </constructor>  </resultMap>  <sql id="Base_Column_List" >    <!--      WARNING - @mbggenerated      This element is automatically generated by MyBatis Generator, do not modify.      This element was generated on Sun Oct 08 14:03:47 CST 2017.    -->    id, parent_id, name, status, sort_order, create_time, update_time  </sql>  <select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Integer" >    <!--      WARNING - @mbggenerated      This element is automatically generated by MyBatis Generator, do not modify.      This element was generated on Sun Oct 08 14:03:47 CST 2017.    -->    select     <include refid="Base_Column_List" />    from happymall_category    where id = #{id,jdbcType=INTEGER}  </select>  <delete id="deleteByPrimaryKey" parameterType="java.lang.Integer" >    <!--      WARNING - @mbggenerated      This element is automatically generated by MyBatis Generator, do not modify.      This element was generated on Sun Oct 08 14:03:47 CST 2017.    -->    delete from happymall_category    where id = #{id,jdbcType=INTEGER}  </delete>  <insert id="insert" parameterType="top.winxblast.happymall.pojo.Category" >    <!--      WARNING - @mbggenerated      This element is automatically generated by MyBatis Generator, do not modify.      This element was generated on Sun Oct 08 14:03:47 CST 2017.    -->    insert into happymall_category (id, parent_id, name,       status, sort_order, create_time,       update_time)    values (#{id,jdbcType=INTEGER}, #{parentId,jdbcType=INTEGER}, #{name,jdbcType=VARCHAR},       #{status,jdbcType=BIT}, #{sortOrder,jdbcType=INTEGER}, now(),      now())  </insert>  <insert id="insertSelective" parameterType="top.winxblast.happymall.pojo.Category" >    <!--      WARNING - @mbggenerated      This element is automatically generated by MyBatis Generator, do not modify.      This element was generated on Sun Oct 08 14:03:47 CST 2017.    -->    insert into happymall_category    <trim prefix="(" suffix=")" suffixOverrides="," >      <if test="id != null" >        id,      </if>      <if test="parentId != null" >        parent_id,      </if>      <if test="name != null" >        name,      </if>      <if test="status != null" >        status,      </if>      <if test="sortOrder != null" >        sort_order,      </if>      <if test="createTime != null" >        create_time,      </if>      <if test="updateTime != null" >        update_time,      </if>    </trim>    <trim prefix="values (" suffix=")" suffixOverrides="," >      <if test="id != null" >        #{id,jdbcType=INTEGER},      </if>      <if test="parentId != null" >        #{parentId,jdbcType=INTEGER},      </if>      <if test="name != null" >        #{name,jdbcType=VARCHAR},      </if>      <if test="status != null" >        #{status,jdbcType=BIT},      </if>      <if test="sortOrder != null" >        #{sortOrder,jdbcType=INTEGER},      </if>      <if test="createTime != null" >        now(),      </if>      <if test="updateTime != null" >        now(),      </if>    </trim>  </insert>  <update id="updateByPrimaryKeySelective" parameterType="top.winxblast.happymall.pojo.Category" >    <!--      WARNING - @mbggenerated      This element is automatically generated by MyBatis Generator, do not modify.      This element was generated on Sun Oct 08 14:03:47 CST 2017.    -->    update happymall_category    <set >      <if test="parentId != null" >        parent_id = #{parentId,jdbcType=INTEGER},      </if>      <if test="name != null" >        name = #{name,jdbcType=VARCHAR},      </if>      <if test="status != null" >        status = #{status,jdbcType=BIT},      </if>      <if test="sortOrder != null" >        sort_order = #{sortOrder,jdbcType=INTEGER},      </if>      <if test="createTime != null" >        create_time = #{createTime,jdbcType=TIMESTAMP},      </if>      <if test="updateTime != null" >        now(),      </if>    </set>    where id = #{id,jdbcType=INTEGER}  </update>  <update id="updateByPrimaryKey" parameterType="top.winxblast.happymall.pojo.Category" >    <!--      WARNING - @mbggenerated      This element is automatically generated by MyBatis Generator, do not modify.      This element was generated on Sun Oct 08 14:03:47 CST 2017.    -->    update happymall_category    set parent_id = #{parentId,jdbcType=INTEGER},      name = #{name,jdbcType=VARCHAR},      status = #{status,jdbcType=BIT},      sort_order = #{sortOrder,jdbcType=INTEGER},      create_time = #{createTime,jdbcType=TIMESTAMP},      update_time = now()    where id = #{id,jdbcType=INTEGER}  </update>  <select id="selectCategoryChildrenByParentId" resultMap="BaseResultMap" parameterType="int">    SELECT    <include refid="Base_Column_List"/>    FROM happymall_category    WHERE parent_id = #{parentId}  </select></mapper>

接口测试

还是继续使用我们的chrome插件restlet client,这里我就上几张图给大家参考一下就好了,还是比较容易使用的,不过测试要尽可能覆盖一些特殊情况,虽然我们不是专业的测试,但是也要考虑的周到一些。
这次的4个接口都是使用GET方法就可以了,带默认参数的可以试试不传入参数。
get_category.do接口
这里写图片描述
这里写图片描述

add_category.do
这里写图片描述

set_category_name.do
这里写图片描述

get_deep_category.do
这里写图片描述

同时由于是使用GET方法提交参数,我们也不需要写HTML表单,可以直接在浏览器中输入相应的地址来查看返回值,这里json格式化的效果是由插件FE助手完成的,大家要是使用火狐浏览器的话可以浏览器直接支持格式化json的。
这里写图片描述

阅读全文
0 0
原创粉丝点击