实战SSM_O2O商铺_27【商品类别】删除商品类别从Dao到View层的开发

简介: 实战SSM_O2O商铺_27【商品类别】删除商品类别从Dao到View层的开发

概述

上篇博客 实战SSM_O2O商铺_26【商品类别】批量新增商品类别从Dao到View层的开发实现了商品目录的批量添加功能,我们按照既定的设计,继续来完成商品目录的修改吧。


Dao层

ProductCategoryDao接口增加接口方法

/**
   * 
   * 
   * @Title: deleteProductCategory
   * 
   * @Description: 删除特定shop下的productCategory
   * 
   * @param productCategoryId
   * @param shopId
   * 
   * @return: int
   */
  int deleteProductCategory(@Param("productCategoryId") Long productCategoryId, @Param("shopId") Long shopId);

ProductCategoryDao SQL映射文件

<delete id="deleteProductCategory">
    DELETE FROM 
      tb_product_category
    WHERE 
      product_category_id = #{productCategoryId}
      and 
      shop_id = #{shopId}
  </delete>

闭环的单元测试

这里我们使用Junit 4.11里及其以后的版本中增加的@FixMethodOrder注解来实现. 具体见代码注释。

package com.artisan.o2o.dao;
import static org.junit.Assert.assertEquals;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.junit.Assert;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runners.MethodSorters;
import org.springframework.beans.factory.annotation.Autowired;
import com.artisan.o2o.BaseTest;
import com.artisan.o2o.entity.ProductCategory;
/**
 * 
 * 
 * @ClassName: ProductCategoryTest
 * 
 * @Description: Junit 4.11里增加了指定测试方法执行顺序的特性 .
 * 
 *               测试类的执行顺序可通过对测试类添加注解@FixMethodOrder(value) 来指定,其中value 为执行顺序
 * 
 *               三种执行顺序可供选择:
 * 
 *               默认(MethodSorters.DEFAULT),
 *               默认顺序由方法名hashcode值来决定,如果hash值大小一致,则按名字的字典顺序确定
 *               由于hashcode的生成和操作系统相关
 *               (以native修饰),所以对于不同操作系统,可能会出现不一样的执行顺序,在某一操作系统上,多次执行的顺序不变
 * 
 *               按方法名( MethodSorters.NAME_ASCENDING)【推荐】,
 *               按方法名称的进行排序,由于是按字符的字典顺序,所以以这种方式指定执行顺序会始终保持一致;
 *               不过这种方式需要对测试方法有一定的命名规则,如 测试方法均以testNNN开头(NNN表示测试方法序列号 001-999)
 * 
 *               JVM(MethodSorters.JVM)
 *               按JVM返回的方法名的顺序执行,此种方式下测试方法的执行顺序是不可预测的,即每次运行的顺序可能都不一样
 * 
 * 
 * @author: Mr.Yang
 * 
 * @date: 2018年6月21日 下午11:55:45
 */
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class ProductCategoryTest extends BaseTest {
  @Autowired
  ProductCategoryDao productCategoryDao;
  @Test
  public void testB_SelectProductCategoryList() {
    long shopId = 5L;
    List<ProductCategory> productCategories = productCategoryDao.selectProductCategoryList(shopId);
    // shopId = 5 有2条测试数据,期望list中有2条
    assertEquals(2, productCategories.size());
    // SQL中按照权重排序, product1 priority 99 ,期望第一条数据是 product1
    assertEquals("product1", productCategories.get(0).getProductCategoryName());
    for (ProductCategory productCategory : productCategories) {
      System.out.println(productCategory.toString());
    }
    productCategories = productCategoryDao.selectProductCategoryList(6L);
    assertEquals(0, productCategories.size());
  }
  @Test
  public void testA_BatchInsertProductCategory() {
    ProductCategory productCategory1 = new ProductCategory();
    productCategory1.setProductCategoryName("product1");
    productCategory1.setProductCategoryDesc("product1_desc");
    productCategory1.setPriority(99);
    productCategory1.setCreateTime(new Date());
    productCategory1.setLastEditTime(new Date());
    productCategory1.setShopId(5L);
    ProductCategory productCategory2 = new ProductCategory();
    productCategory2.setProductCategoryName("product2");
    productCategory2.setProductCategoryDesc("product2_desc");
    productCategory2.setPriority(98);
    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);
  }
  @Test
  public void testC_DeleteProductCategory() {
    // 查询出来shopId=5的商铺下面全部的商品目录
    List<ProductCategory> productCategoryList = productCategoryDao.selectProductCategoryList(5L);
    // 遍历循环删除
    for (ProductCategory productCategory : productCategoryList) {
      if ("product1".equals(productCategory.getProductCategoryName()) || "product2".equals(productCategory.getProductCategoryName())) {
        int effectNum = productCategoryDao.deleteProductCategory(productCategory.getProductCategoryId(), 5L);
        assertEquals(1, effectNum);
      }
    }
  }
}

运行单元测试

日志信息:

JDBC Connection [com.mchange.v2.c3p0.impl.NewProxyConnection@7fb95505] will not be managed by Spring
==>  Preparing: INSERT INTO tb_product_category( product_category_name, product_category_desc, priority, create_time, last_edit_time, shop_id) VALUES ( ?, ?, ?, ?, ?, ? ) , ( ?, ?, ?, ?, ?, ? ) 
==> Parameters: product1(String), product1_desc(String), 99(Integer), 2018-06-22 00:17:25.611(Timestamp), 2018-06-22 00:17:25.611(Timestamp), 5(Long), product2(String), product2_desc(String), 98(Integer), 2018-06-22 00:17:25.612(Timestamp), 2018-06-22 00:17:25.612(Timestamp), 5(Long)
<==    Updates: 2
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@38b27cdc]
Creating a new SqlSession
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@336f1079] was not registered for synchronization because synchronization is not active
JDBC Connection [com.mchange.v2.c3p0.impl.NewProxyConnection@21fd5faa] will not be managed by Spring
==>  Preparing: SELECT tpc.product_category_id, tpc.product_category_name, tpc.product_category_desc, tpc.priority, tpc.create_time, tpc.last_edit_time, tpc.shop_id FROM tb_product_category tpc WHERE tpc.shop_id = ? ORDER BY priority DESC 
==> Parameters: 5(Long)
<==    Columns: product_category_id, product_category_name, product_category_desc, priority, create_time, last_edit_time, shop_id
<==        Row: 24, product1, product1_desc, 99, 2018-06-22 00:17:26.0, 2018-06-22 00:17:26.0, 5
<==        Row: 25, product2, product2_desc, 98, 2018-06-22 00:17:26.0, 2018-06-22 00:17:26.0, 5
<==      Total: 2
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@336f1079]
ProductCategory [productCategoryId=24, shopId=5, productCategoryName=product1, productCategoryDesc=product1_desc, priority=99, createTime=Fri Jun 22 00:17:26 BOT 2018, lastEditTime=Fri Jun 22 00:17:26 BOT 2018]
ProductCategory [productCategoryId=25, shopId=5, productCategoryName=product2, productCategoryDesc=product2_desc, priority=98, createTime=Fri Jun 22 00:17:26 BOT 2018, lastEditTime=Fri Jun 22 00:17:26 BOT 2018]
Creating a new SqlSession
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@19b93fa8] was not registered for synchronization because synchronization is not active
JDBC Connection [com.mchange.v2.c3p0.impl.NewProxyConnection@1f010bf0] will not be managed by Spring
==>  Preparing: SELECT tpc.product_category_id, tpc.product_category_name, tpc.product_category_desc, tpc.priority, tpc.create_time, tpc.last_edit_time, tpc.shop_id FROM tb_product_category tpc WHERE tpc.shop_id = ? ORDER BY priority DESC 
==> Parameters: 6(Long)
<==      Total: 0
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@19b93fa8]
Creating a new SqlSession
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@7f132176] was not registered for synchronization because synchronization is not active
JDBC Connection [com.mchange.v2.c3p0.impl.NewProxyConnection@2631f68c] will not be managed by Spring
==>  Preparing: SELECT tpc.product_category_id, tpc.product_category_name, tpc.product_category_desc, tpc.priority, tpc.create_time, tpc.last_edit_time, tpc.shop_id FROM tb_product_category tpc WHERE tpc.shop_id = ? ORDER BY priority DESC 
==> Parameters: 5(Long)
<==    Columns: product_category_id, product_category_name, product_category_desc, priority, create_time, last_edit_time, shop_id
<==        Row: 24, product1, product1_desc, 99, 2018-06-22 00:17:26.0, 2018-06-22 00:17:26.0, 5
<==        Row: 25, product2, product2_desc, 98, 2018-06-22 00:17:26.0, 2018-06-22 00:17:26.0, 5
<==      Total: 2
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@7f132176]
Creating a new SqlSession
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@5443d039] was not registered for synchronization because synchronization is not active
JDBC Connection [com.mchange.v2.c3p0.impl.NewProxyConnection@7d1cfb8b] will not be managed by Spring
==>  Preparing: DELETE FROM tb_product_category WHERE product_category_id = ? and shop_id = ? 
==> Parameters: 24(Long), 5(Long)
<==    Updates: 1
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@5443d039]
Creating a new SqlSession
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@6e4566f1] was not registered for synchronization because synchronization is not active
JDBC Connection [com.mchange.v2.c3p0.impl.NewProxyConnection@344f4dea] will not be managed by Spring
==>  Preparing: DELETE FROM tb_product_category WHERE product_category_id = ? and shop_id = ? 
==> Parameters: 25(Long), 5(Long)
<==    Updates: 1
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@6e4566f1]

Servie层

接口

/**
   * 
   * 
   * @Title: deleteProductCategory
   * 
   * @Description: TODO 需要先将该商品目录下的商品的类别Id置为空,然后再删除该商品目录, 因此需要事务控制
   * 
   * @param productCategoryId
   * @param shopId
   * @throws ProductCategoryOperationException
   * 
   * @return: ProductCategoryExecution
   */
  ProductCategoryExecution deleteProductCategory(long productCategoryId, long shopId) throws ProductCategoryOperationException;

接口实现

/**
   * TODO 需要先将该商品目录下的商品的类别Id置为空,然后再删除该商品目录, 因此需要事务控制@Transactional
   */
  @Override
  @Transactional
  public ProductCategoryExecution deleteProductCategory(long productCategoryId, long shopId) throws ProductCategoryOperationException {
    // TODO 第一步 需要先将该商品目录下的商品的类别Id置为空
    // 第二步 删除该商品目录
    try {
      int effectNum = productCategoryDao.deleteProductCategory(productCategoryId, shopId);
      if (effectNum > 0) {
        return new ProductCategoryExecution(ProductCategoryStateEnum.SUCCESS);
      } else {
        return new ProductCategoryExecution(ProductCategoryStateEnum.INNER_ERROR);
      }
    } catch (Exception e) {
      throw new ProductCategoryOperationException(e.getMessage());
    }
  }

单元测试

@Test
  public void testDeleteProductCategory() {
    ProductCategoryExecution productCategoryExecution = productCategoryService.deleteProductCategory(26, 5);
    Assert.assertEquals(1, productCategoryExecution.getState());
    ProductCategoryExecution productCategoryExecution2 = productCategoryService.deleteProductCategory(27, 5);
    Assert.assertEquals(1, productCategoryExecution2.getState());
  }

Controller层

路由方法

/**
   * 
   * 
   * @Title: remooveProductCategory
   * 
   * @Description: 删除商品目录
   * 
   * @param productCategoryId
   * @param request
   * 
   * @return: Map<String,Object>
   */
  @RequestMapping(value = "/removeproductcategory", method = RequestMethod.POST)
  @ResponseBody
  public Map<String, Object> remooveProductCategory(Long productCategoryId, HttpServletRequest request) {
    Map<String, Object> modelMap = new HashMap<String, Object>();
    if (productCategoryId != null && productCategoryId > 0) {
      // 从session中获取shop的信息
      Shop currentShop = (Shop) request.getSession().getAttribute("currentShop");
      if (currentShop != null && currentShop.getShopId() != null) {
        try {
          // 删除
          Long shopId = currentShop.getShopId();
          ProductCategoryExecution pce = productCategoryService.deleteProductCategory(productCategoryId, shopId);
          if (pce.getState() == ProductCategoryStateEnum.SUCCESS.getState()) {
            modelMap.put("success", true);
          } 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

增加如下代码

var deleteProductCategoryUrl = '/o2o/shopadmin/removeproductcategory';
// 一种是需要提交到后台的删除  now  ,另外一种是 新增但未提交到数据库中的删除 temp
  $('.product-categroy-wrap').on('click', '.row-product-category.now .delete',
      function(e) {
        var target = e.currentTarget;
        $.confirm('确定么?', function() {
          $.ajax({
            url : deleteProductCategoryUrl,
            type : 'POST',
            data : {
              productCategoryId : target.dataset.id,
            },
            dataType : 'json',
            success : function(data) {
              if (data.success) {
                $.toast('删除成功!');
                // 重新加载数据
                getProductCategoryList();
              } else {
                $.toast('删除失败!');
              }
            }
          });
        });
      });
  $('.product-categroy-wrap').on('click', '.row-product-category.temp .delete',
      function(e) {
        $(this).parent().parent().remove();
      });

联调

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

效果如下:


Github地址

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


相关文章
|
10天前
|
前端开发 Oracle 关系型数据库
关于使用SSM+JSP开发时setter、getter隐式调用问题的小结
本文主要分享了在使用SSM+JSP进行网站开发时,因忽视setter、getter的隐式调用问题而导致的常见bug及其解决方法。详细介绍了setter和getter的隐式调用时机,并给出了具体示例,帮助开发者避免类似问题。
37 11
|
5月前
|
搜索推荐 JavaScript Java
计算机Java项目|基于SSM的个性化商铺系统
计算机Java项目|基于SSM的个性化商铺系统
|
5月前
|
前端开发
杨校老师之基于SSM开发的校园点餐配送系统
杨校老师之基于SSM开发的校园点餐配送系统
60 0
杨校老师之基于SSM开发的校园点餐配送系统
|
5月前
|
Web App开发 前端开发 JavaScript
基于ssm+layui开发汽车租赁管理系统
基于ssm+layui开发汽车租赁管理系统
40 0
|
5月前
|
JavaScript Java 测试技术
基于ssm+vue.js+uniapp小程序的二手交易平台设计与开发附带文章和源代码部署视频讲解等
基于ssm+vue.js+uniapp小程序的二手交易平台设计与开发附带文章和源代码部署视频讲解等
39 0
|
3月前
|
Java 数据库连接 Maven
手把手教你如何搭建SSM框架、图书商城系统案例
这篇文章是关于如何搭建SSM框架以及实现一个图书商城系统的详细教程,包括了项目的配置文件整合、依赖管理、项目结构和运行效果展示,并提供了GitHub源码链接。
手把手教你如何搭建SSM框架、图书商城系统案例
|
2月前
|
Java 应用服务中间件 数据库连接
ssm项目整合,简单的用户管理系统
文章介绍了一个使用SSM框架(Spring、SpringMVC、MyBatis)构建的简单用户管理系统的整合过程,包括项目搭建、数据库配置、各层代码实现以及视图展示。
ssm项目整合,简单的用户管理系统
|
5月前
|
前端开发 JavaScript Java
计算机Java项目|SSM智能仓储系统
计算机Java项目|SSM智能仓储系统
|
2月前
|
XML Java 数据库连接
如何搭建SSM框架、图书商城系统
这是一份详尽的《Spring + SpringMVC + Mybatis 整合指南》,作者耗时良久整理出约五万字的内容,现已经全部笔记公开。此文档详细地介绍了如何搭建与整合SSM框架,具体步骤包括创建Maven项目、添加web骨架、配置pom文件以及整合Spring、SpringMVC和Mybatis等。无论是对初学者还是有一定基础的开发者来说,都是很好的学习资源。此外,作者还提供了项目源码的GitHub链接,方便读者实践。虽然当前主流推荐学习SpringBoot,但了解SSM框架仍然是不可或缺的基础。
35 0
|
3月前
|
SQL Java 应用服务中间件
使用SSM搭建图书商城管理系统(完整过程介绍、售后服务哈哈哈)
这篇文章是关于如何使用SSM框架搭建图书商城管理系统的教程,包括完整过程介绍、常见问题解答和售后服务,提供了项目地址、运行环境配置、效果图展示以及运行代码的步骤。
使用SSM搭建图书商城管理系统(完整过程介绍、售后服务哈哈哈)