实战SSM_O2O商铺_26【商品类别】商品类别批量新增从Dao到View层的开发

概述

上一篇博文 实战SSM_O2O商铺_25【商品类别】商品类别列表展示从Dao到View层的开发 ,我们完成了 商品类别 列表展示的开发,接下来,我们继续来完成 【批量添加商品类别】的功能吧。


Dao层

ProductCategoryDao接口

/**
     * 
     * 
     * @Title: batchInsertProductCategory
     * 
     * @Description: 批量增加roductCategory
     * 
     * @param productCategoryList
     * 
     * @return: int
     */
    int batchInsertProductCategory(List<ProductCategory> productCategoryList);

ProductCategoryDao SQL映射文件

<insert id="batchInsertProductCategory" parameterType="java.util.List">
        INSERT INTO
            tb_product_category(
                product_category_name,
                product_category_desc,
                priority,
                create_time,
                last_edit_time,
                shop_id)
         VALUES 
         <foreach collection="list" item="productCategory" index="index" separator=",">
            (
                #{productCategory.productCategoryName},
                #{productCategory.productCategoryDesc},
                #{productCategory.priority},
                #{productCategory.createTime},
                #{productCategory.lastEditTime},
                #{productCategory.shopId}
            )
         </foreach>
    </insert>

单元测试

@Test
    public void testBatchInsertProductCategory() {

        ProductCategory productCategory1 = new ProductCategory();
        productCategory1.setProductCategoryName("ProductCategoryTest1");
        productCategory1.setProductCategoryDesc("ProductCategoryTest1-desc");
        productCategory1.setPriority(300);
        productCategory1.setCreateTime(new Date());
        productCategory1.setLastEditTime(new Date());
        productCategory1.setShopId(5L);

        ProductCategory productCategory2 = new ProductCategory();
        productCategory2.setProductCategoryName("ProductCategoryTest2");
        productCategory2.setProductCategoryDesc("ProductCategoryTest2-desc");
        productCategory2.setPriority(600);
        productCategory2.setCreateTime(new Date());
        productCategory2.setLastEditTime(new Date());
        productCategory2.setShopId(5L);

        List<ProductCategory> productCategoryList = new ArrayList<ProductCategory>();
        productCategoryList.add(productCategory1);
        productCategoryList.add(productCategory2);

        int effectNum = productCategoryDao.batchInsertProductCategory(productCategoryList);
        Assert.assertEquals(2, effectNum);

    }

单元测试OK。


Service层

ProductCategoryExecution DTO类的开发

我们需要增加操作的状态及数量等信息,因此单独的Domain类已经无法满足需求了,因此我们使用DTO来扩展实体类的功能

package com.artisan.o2o.dto;

import java.util.List;

import com.artisan.o2o.entity.ProductCategory;
import com.artisan.o2o.enums.ProductCategoryStateEnum;

/**
 * 
 * 
 * @ClassName: ProductCategoryExecution
 * 
 * @Description: 封装操作ProductCategory的返回结果,包括操作状态和ProductCategory信息
 * 
 * @author: Mr.Yang
 * 
 * @date: 2018年6月21日 上午12:17:07
 */
public class ProductCategoryExecution {

    private int state;
    private String stateInfo;

    // 因为是批量操作,所以使用List
    private List<ProductCategory> productCategoryList;

    private int count;


    /**
     * 
     * 
     * @Title:ProductCategoryExecution
     * 
     * @Description:空的构造函数
     */
    public ProductCategoryExecution() {
        super();
    }


    /**
     * 
     * 
     * @Title:ProductCategoryExecution
     * 
     * @Description:操作成功的时候使用的构造函数,返回操作状态和ProductCategory集合
     * 
     * @param productCategoryStateEnum
     * @param productCategoryList
     * @param count
     */
    public ProductCategoryExecution(ProductCategoryStateEnum productCategoryStateEnum, List<ProductCategory> productCategoryList, int count) {
        this.state = productCategoryStateEnum.getState();
        this.stateInfo = productCategoryStateEnum.getStateInfo();
        this.productCategoryList = productCategoryList;
        this.count = count;
    }


    /**
     * 
     * 
     * @Title:ProductCategoryExecution
     * 
     * @Description:操作失败的时候返回的信息,仅包含状态和状态描述即可
     * 
     * @param productCategoryStateEnum
     */
    public ProductCategoryExecution(ProductCategoryStateEnum productCategoryStateEnum) {
        this.state = productCategoryStateEnum.getState();
        this.stateInfo = productCategoryStateEnum.getStateInfo();
    }

    public int getState() {
        return state;
    }

    public void setState(int state) {
        this.state = state;
    }

    public String getStateInfo() {
        return stateInfo;
    }

    public void setStateInfo(String stateInfo) {
        this.stateInfo = stateInfo;
    }

    public List<ProductCategory> getProductCategoryList() {
        return productCategoryList;
    }

    public void setProductCategoryList(List<ProductCategory> productCategoryList) {
        this.productCategoryList = productCategoryList;
    }

    public int getCount() {
        return count;
    }

    public void setCount(int count) {
        this.count = count;
    }

}

ProductCategoryStateEnum 增加几个标识

SUCCESS(1, "操作成功"), INNER_ERROR(-1001, "操作失败"), NULL_SHOP(-1002, "Shop信息为空"), EMPETY_LIST(-1003, "请输入商品目录信息");

封装特定异常类

批量添加,这里我们使用事务控制

package com.artisan.o2o.exception;

/**
 * 
 * 
 * @ClassName: ProductCategoryOperationException
 * 
 * @Description: 继承RuntimeException,便于异常时候的回滚。 保持所有的操作在一个事务中。
 * 
 *               这样在标注了@Transactional事务的方法中,出现了异常,才会回滚数据。
 * 
 *               默认情况下,如果在事务中抛出了未检查异常(继承自 RuntimeException 的异常)或者 Error,则 Spring
 *               将回滚事务;除此之外,Spring 不会回滚事务。
 * 
 * 
 * @author: Mr.Yang
 * 
 * @date: 2018年6月21日 上午12:22:44
 */
public class ProductCategoryOperationException extends RuntimeException {

    private static final long serialVersionUID = 6500682256313143297L;

    public ProductCategoryOperationException(String message) {
        super(message);
    }

}

ProductCategoryService接口

/**
     * 
     * 
     * @Title: addProductCategory
     * 
     * @Description: 批量插入ProductCategory
     * 
     * @param productCategoryList
     * @throws ProductCategoryOperationException
     * 
     * @return: ProductCategoryExecution
     */
    ProductCategoryExecution addProductCategory(List<ProductCategory> productCategoryList) throws ProductCategoryOperationException;

ProductCategoryServiceImpl实现类

/**
     * 使用@Transactional控制事务
     */
    @Override
    @Transactional
    public ProductCategoryExecution addProductCategory(List<ProductCategory> productCategoryList) throws ProductCategoryOperationException {
        // 非空判断
        if (productCategoryList != null && productCategoryList.size() > 0) {
            try {
                // 批量增加ProductCategory
                int effectNum = productCategoryDao.batchInsertProductCategory(productCategoryList);
                if (effectNum > 0) {
                    return new ProductCategoryExecution(ProductCategoryStateEnum.SUCCESS, productCategoryList, effectNum);
                } else {
                    return new ProductCategoryExecution(ProductCategoryStateEnum.INNER_ERROR);
                }
            } catch (Exception e) {
                e.printStackTrace();
                throw new ProductCategoryOperationException("batchAddProductCategory Error:" + e.getMessage());
            }
        } else {
            return new ProductCategoryExecution(ProductCategoryStateEnum.EMPETY_LIST);
        }
    }

单元测试

@Test
    public void testAddProductCategory() {
        ProductCategory productCategory1 = new ProductCategory();
        productCategory1.setProductCategoryName("ProductCategoryTest3");
        productCategory1.setProductCategoryDesc("ProductCategoryTest3-desc");
        productCategory1.setPriority(300);
        productCategory1.setCreateTime(new Date());
        productCategory1.setLastEditTime(new Date());
        productCategory1.setShopId(5L);

        ProductCategory productCategory2 = new ProductCategory();
        productCategory2.setProductCategoryName("ProductCategoryTest4");
        productCategory2.setProductCategoryDesc("ProductCategoryTest4-desc");
        productCategory2.setPriority(600);
        productCategory2.setCreateTime(new Date());
        productCategory2.setLastEditTime(new Date());
        productCategory2.setShopId(5L);

        List<ProductCategory> productCategoryList = new ArrayList<ProductCategory>();
        productCategoryList.add(productCategory1);
        productCategoryList.add(productCategory2);

        ProductCategoryExecution productCategoryExecution = productCategoryService.addProductCategory(productCategoryList);

        Assert.assertEquals(1, productCategoryExecution.getState());
        Assert.assertEquals(2, productCategoryExecution.getProductCategoryList().size());
    }

单元测试通过。


Controller层

ProductCategoryController增加addProductCategory方法

/**
     * 
     * 
     * @Title: addProductCategory
     * 
     * @Description: 添加商铺目录 ,使用@RequestBody接收前端传递过来的productCategoryList
     * 
     * @param productCategoryList
     * @param request
     * 
     * @return: Map<String,Object>
     */
    @RequestMapping(value = "/addproductcategory", method = RequestMethod.POST)
    @ResponseBody
    public Map<String, Object> addProductCategory(@RequestBody List<ProductCategory> productCategoryList, HttpServletRequest request) {
        Map<String, Object> modelMap = new HashMap<String, Object>();
        if (productCategoryList != null && productCategoryList.size() > 0) {
            // 从session中获取shop的信息
            Shop currentShop = (Shop) request.getSession().getAttribute("currentShop");
            if (currentShop != null && currentShop.getShopId() != null) {
                // 为ProductCategory设置shopId
                for (ProductCategory productCategory : productCategoryList) {
                    productCategory.setShopId(currentShop.getShopId());
                }
                try {
                    // 批量插入
                    ProductCategoryExecution pce = productCategoryService.addProductCategory(productCategoryList);
                    if (pce.getState() == ProductCategoryStateEnum.SUCCESS.getState()) {
                        modelMap.put("success", true);
                        // 同时也将新增成功的数量返回给前台
                        modelMap.put("effectNum", pce.getCount());
                    } else {
                        modelMap.put("success", false);
                        modelMap.put("errMsg", pce.getStateInfo());
                    }
                } catch (ProductCategoryOperationException e) {
                    e.printStackTrace();
                    modelMap.put("success", false);
                    modelMap.put("errMsg", e.getMessage());
                    return modelMap;
                }
            } else {
                modelMap.put("success", false);
                modelMap.put("errMsg", ProductCategoryStateEnum.NULL_SHOP.getStateInfo());
            }
        } else {
            modelMap.put("success", false);
            modelMap.put("errMsg", "至少输入一个店铺目录信息");
        }
        return modelMap;
    }

单元测试

待前端页面完成,一并测试


View层

productcategorymanage.js

$(function () {
    // 后台从session中获取shop的信息,这里就不传shopId了
    //var shopId = getQueryString("shopId");
    //var productCategoryURL = '/o2o/shopadmin/getproductcategorybyshopId?shopId=' + shopId;

    var getProductCategoryURL = '/o2o/shopadmin/getproductcategorybyshopId';
    var addProductCategoryURL = '/o2o/shopadmin/addproductcategory';
    // 调用getProductCategoryList,加载数据
    getProductCategoryList();

    function getProductCategoryList() {
        $.getJSON(getProductCategoryURL,
                    function(data) {
                        if (data.success) {
                            var dataList = data.data;
                            $('.product-categroy-wrap').html('');
                            var tempHtml = '';
                            dataList
                                    .map(function(item, index) {
                                        tempHtml += ''
                                                + '<div class="row row-product-category now">'
                                                + '<div class="col-33 product-category-name">'
                                                + item.productCategoryName
                                                + '</div>'
                                                + '<div class="col-33">'
                                                + item.priority
                                                + '</div>'
                                                + '<div class="col-33"><a href="#" class="button delete" data-id="'
                                                + item.productCategoryId
                                                + '">删除</a></div>'
                                                + '</div>';
                                    });
                            $('.product-categroy-wrap').append(tempHtml);
                        }
                    });
    }



    //  新增按钮的点击事件
    $('#new').click(
            function(){
                // 新增数据 以 temp 为标识,便于和库表中的数据区分开来
                var tempHtml = '<div class="row row-product-category temp">'
                    + '<div class="col-33"><input class="category-input category" type="text" placeholder="分类名"></div>'
                    + '<div class="col-33"><input class="category-input priority" type="number" placeholder="优先级"></div>'
                    + '<div class="col-33"><a href="#" class="button delete">删除</a></div>'
                    + '</div>';
                $('.product-categroy-wrap').append(tempHtml);
            });


    $('#submit').click(function() {
        // 通过temp 获取新增的行
        var tempArr = $('.temp');
        // 定义数组接收新增的数据
        var productCategoryList = [];
        tempArr.map(function(index, item) {
            var tempObj = {};
            tempObj.productCategoryName = $(item).find('.category').val();
            tempObj.priority = $(item).find('.priority').val();
            if (tempObj.productCategoryName && tempObj.priority) {
                productCategoryList.push(tempObj);
            }
        });
        $.ajax({
            url : addProductCategoryURL,
            type : 'POST',
            // 后端通过 @HttpRequestBody直接接收
            data : JSON.stringify(productCategoryList),
            contentType : 'application/json',
            success : function(data) {
                if (data.success) {
                    $.toast('新增【' + data.effectNum + '】条成功!');
                    // 重新加载数据
                    getProductCategoryList();
                } else {
                    $.toast(data.errMsg);
                }
            }
        });
    });

});

前后端联调

前端页面debug, 后端也可以加入断点,以debug的方式开启tomcat,逐步调测

效果如下:

这里写图片描述

库表数据:

这里写图片描述


Github地址

代码地址: https://github.com/yangshangwei/o2o

猜你喜欢

转载自blog.csdn.net/yangshangwei/article/details/80764157
今日推荐