Skip to content

springboot项目学习笔记4 商品模块

仲灏2022-04-09约 1 分钟

商品模块介绍

后台

  • 新增商品
    • 图片上传
  • 更新商品
  • 删除商品
  • 批量上下架操作
  • 商品列表

前台


  • 商品列表

    • 分类

    • 排序价格

  • 商品详情

添加商品

  • 添加后台商品管理controller

    @RestController 相当于在每个方法上都加了@ResponseBody

    java
    package com.izhaong.mall.contraoller;
    ...
    @RestController
    public class ProductAdminController {
    
        @Autowired
        ProductService productService;
      
    		@PostMapping("/admin/product/add")
        public ApiRestResponse addProduct(@Valid @RequestBody AddProductReq addProductReq) {
            productService.add(addProductReq);
            return ApiRestResponse.success();
        }
    }
  • 新增商品实体类 自定义在model request

    • 添加校验

      java
      package com.izhaong.mall.model.request;
      
      import javax.validation.constraints.Max;
      import javax.validation.constraints.Min;
      import javax.validation.constraints.NotNull;
      
      public class AddProductReq {
          @NotNull(message = "商品名称不能为null")
          private String name;
      
          @NotNull(message = "商品图片不能为null")
      
          private String image;
      
          private String detail;
      
          @NotNull(message = "商品分类不能为null")
          private Integer categoryId;
      
          @NotNull(message = "商品价格不能为null")
          @Min(value = 1,message = "价格不能小于1")
          private Integer price;
      
          @NotNull(message = "商品库存不能为null")
          @Max(value = 10000,message = "库存不能大于10000")
          private Integer stock;
      
          private Integer status;
      		...	getter&setter
      }
  • 建立商品service

    • 接口

      java
      package com.izhaong.mall.service;
      
      import com.github.pagehelper.PageInfo;
      import com.izhaong.mall.model.pojo.Product;
      import com.izhaong.mall.model.request.AddProductReq;
      import com.izhaong.mall.model.vo.CategoryVO;
      
      import java.util.List;
      
      public interface ProductService {
          void add(AddProductReq addProductReq);
      
          void update(Product product);
      
          void delete(Integer id);
      
          PageInfo listForAdmin(Integer pageNum, Integer pageSize);
      
          List<CategoryVO> listForCustomer();
      }
    • 实现类

      java
      package com.izhaong.mall.service.impl;
      ...
      @Service
      public class ProductServiceImpl implements ProductService {
      
          @Autowired
          ProductMapper productMapper;
      
          @Override
          public void add(AddProductReq addProductReq) {
              Product product = new Product();
              BeanUtils.copyProperties(addProductReq, product);
              // 重名情况处理
      
          }
      
          @Override
          public void update(Product product) {
      
          }
      
          @Override
          public void delete(Integer id) {
      
          }
      
          @Override
          public PageInfo listForAdmin(Integer pageNum, Integer pageSize) {
              return null;
          }
      
          @Override
          public List<CategoryVO> listForCustomer() {
              return null;
          }
      }
      • 重名情况处理:

        • 根据name查询, 新增mapper

          java
          package com.izhaong.mall.model.dao;
          ...
          public interface ProductMapper {
          	...
            Product selectByPrimaryKey(Integer id);
            Product selectByName(String name);
            ...
          }
          xml
            ...
          	<select id="selectByName" parameterType="java.lang.String" resultMap="BaseResultMap">
              select
              <include refid="Base_Column_List" />
              from imooc_mall_product
              where name = #{name,jdbcType=VARCHAR}
            </select>
          	...
        • 如果有抛出异常,否则就插入

          java
          @Service
          public class ProductServiceImpl implements ProductService {
          
              @Autowired
              ProductMapper productMapper;
          
              @Override
              public void add(AddProductReq addProductReq) {
                  Product product = new Product();
                  BeanUtils.copyProperties(addProductReq, product);
                  // 重名情况处理
                  Product productOld = productMapper.selectByName(addProductReq.getName());
                  if(productOld != null) {
                      throw new MallException(MallExceptionEnum.NAME_EXISTED);
                  }
                  int count = productMapper.insertSelective(product);
                  if(count == 0) {
                      throw new MallException(MallExceptionEnum.INSERT_FAILED);
                  }
              }
            ...
          }

UUID介绍

  • 文件名UUID
  • 通用唯一识别码(Universally Unique Identifier )
  • 防止重名、防止爬图
  • 生成规则:日期和时间、MAC地址、HashCode、随机数

图片上传

  • 重命名上传文件

    java
        @PostMapping("/admin/upload/file")
        public ApiRestResponse upload (HttpServletRequest httpServletRequest, @RequestParam("file")MultipartFile file) {
            String fileName = file.getOriginalFilename();
            String suffixName = fileName.substring(fileName.lastIndexOf("."));
    
            UUID uuid = UUID.randomUUID();
            String newFileName = uuid.toString() + suffixName;
    
    				...
        }
  • 创建文件

    • 文件夹路径为配置变量

      java
      package com.imooc.mall.common;
      ...
      public class Constant {
          ...
        	public static String FILE_UPLOAD_DIR;
      
          @Value("${file.upload.dir}")
          public void setFileUploadDir(String fileUploadDir) {
              FILE_UPLOAD_DIR = fileUploadDir;
          }
          ...
      }
      • 文件夹吐过没有则创建, 对创建失败的情况做处理

        java
               //如果文件夹不存在
                if (!fileDirectory.exists()) {
                    if (!fileDirectory.mkdir()) {
                        throw new MallException(MallExceptionEnum.MKDIR_FAILED);
                    }
                }
    • 写入空文件中

      java
              try {
                  file.transferTo(destFile);
              } catch (IOException e) {
                  e.printStackTrace();
              }
    • 返回地址

      • 获取本地服务地址

        java
            private URI getHost(URI uri) {
                URI effectiveURI;
                try {
                    effectiveURI = new URI(uri.getScheme(), uri.getUserInfo(), uri.getHost(), uri.getPort(),
                            null, null, null);
                } catch (URISyntaxException e) {
                    effectiveURI = null;
                }
                return effectiveURI;
            }
      • 拼接地址,对失败做处理

        java
                try {
                    return ApiRestResponse
                            .success(getHost(new URI(httpServletRequest.getRequestURL() + "")) + "/images/"
                                    + newFileName);
                } catch (URISyntaxException e) {
                    return ApiRestResponse.error(MallExceptionEnum.UPLOAD_FAILED);
                }

自定义静态资源映射目录

  • 上传图片后回显
  • 配置SpringBootWebMvcConfig
  • 静态资源到本地目录映射
  • 演示打开图片

更新商品

model UpdateProductReq

​ 一定要生成id和name的 getter和setter方法,在controller会用到id的get方法,在service实现类中用到了name的get方法

java
public class UpdateProductReq {
    @NotNull(message = "id不能为空")
    private Integer id;

    private String name;

    private String image;

    private String detail;

    private Integer categoryId;

    @Min(value = 1, message = "价格不能小于1")
    private Integer price;

    @Max(value = 10000, message = "库存不能大于10000")
    private Integer stock;

    private Integer status;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

controller

java
    @PutMapping("/admin/product/update")
    public ApiRestResponse update(UpdateProductReq upProduct) {
        Product product = new Product();
        BeanUtils.copyProperties(upProduct, product);
        productService.update(product);
        return ApiRestResponse.success();
    }

service

  • 同名且不同id

    java
        @Override
        public void update(Product product) {
    //        同名且不同id
            Product productOld = productMapper.selectByName(product.getName());
            if (productOld != null && !(productOld.getId().equals(product.getId()))) {
                throw new MallException(MallExceptionEnum.NAME_EXISTED);
            }
            int count = productMapper.updateByPrimaryKeySelective(product);
            if (count == 0) {
                throw new MallException(MallExceptionEnum.UPDATE_FAILD);
            }
        }

删除商品

controller

java
    @DeleteMapping("/admin/product/delete")
    public ApiRestResponse delete(int id) {
        productService.delete(id);
        return ApiRestResponse.success();
    }

service

java
    @Override
    public void delete(Integer id) {
        Product product = productMapper.selectByPrimaryKey(id);
        if (product == null) {
            throw new MallException(MallExceptionEnum.UPDATE_FAILD);
        }
        int count = productMapper.deleteByPrimaryKey(id);
        if (count == 0) {
            throw new MallException(MallExceptionEnum.DELETE_FAILED);
        }
    }

批量上下架

  • mybatis 遍历list
  • where 语句拼接

mapper

跟mybatis相关需要加入注解的名字@Param

java
    int batchUpdateSellStatus(@Param("ids") Integer[] ids, @Param("status") Integer status);

sql mapper

xml
    <update id="batchUpdateSellStatus">
        update imooc_mall_product
        set status = #{status}
        where id in
        <foreach collection="ids" open="(" close=")" item="id" separator=",">
            #{id}
        </foreach>
    </update>

SQL理解

  • 使用mysql 自带的语句构建批量更新

    mysql
    UPDATE tableName
        SET orderId = CASE id 
            WHEN 1 THEN 3 
            WHEN 2 THEN 4 
            WHEN 3 THEN 5 
        END
    WHERE id IN (1,2,3)

更新多个值的话

mysql
UPDATE categories 
    SET orderId = CASE id 
        WHEN 1 THEN 3 
        WHEN 2 THEN 4 
        WHEN 3 THEN 5 
    END, 
    title = CASE id 
        WHEN 1 THEN 'New Title 1'
        WHEN 2 THEN 'New Title 2'
        WHEN 3 THEN 'New Title 3'
    END
WHERE id IN (1,2,3)

商品列表

  • 排序功能
  • mybatis pagehelper
  • 枚举:order by

service

  • 新建req类
  • 新建query类