springboot项目学习笔记4 商品模块
# 商品模块介绍
后台
- 新增商品
- 图片上传
- 更新商品
- 删除商品
- 批量上下架操作
- 商品列表
前台
商品列表
分类
排序价格
商品详情
# 添加商品
# 添加后台商品管理controller
@RestController 相当于在每个方法上都加了@ResponseBody
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(); } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14# 新增商品实体类 自定义在model request
添加校验
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 }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# 建立商品service
接口
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(); }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21实现类
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; } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37重名情况处理:
根据name查询, 新增mapper
package com.izhaong.mall.model.dao; ... public interface ProductMapper { ... Product selectByPrimaryKey(Integer id); Product selectByName(String name); ... }
1
2
3
4
5
6
7
8... <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> ...
1
2
3
4
5
6
7
8
9如果有抛出异常,否则就插入
@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); } } ... }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# UUID介绍
- 文件名UUID
- 通用唯一识别码(Universally Unique Identifier )
- 防止重名、防止爬图
- 生成规则:日期和时间、MAC地址、HashCode、随机数
# 图片上传
# 重命名上传文件
@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; ... }
1
2
3
4
5
6
7
8
9
10# 创建文件
文件夹路径为配置变量
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; } ... }
1
2
3
4
5
6
7
8
9
10
11
12文件夹吐过没有则创建, 对创建失败的情况做处理
//如果文件夹不存在 if (!fileDirectory.exists()) { if (!fileDirectory.mkdir()) { throw new MallException(MallExceptionEnum.MKDIR_FAILED); } }
1
2
3
4
5
6
写入空文件中
try { file.transferTo(destFile); } catch (IOException e) { e.printStackTrace(); }
1
2
3
4
5返回地址
获取本地服务地址
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; }
1
2
3
4
5
6
7
8
9
10拼接地址,对失败做处理
try { return ApiRestResponse .success(getHost(new URI(httpServletRequest.getRequestURL() + "")) + "/images/" + newFileName); } catch (URISyntaxException e) { return ApiRestResponse.error(MallExceptionEnum.UPLOAD_FAILED); }
1
2
3
4
5
6
7
# 自定义静态资源映射目录
- 上传图片后回显
- 配置SpringBootWebMvcConfig
- 静态资源到本地目录映射
- 演示打开图片
# 更新商品
# model UpdateProductReq
一定要生成id和name的 getter和setter方法,在controller会用到id的get方法,在service实现类中用到了name的get方法
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;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# controller
@PutMapping("/admin/product/update")
public ApiRestResponse update(UpdateProductReq upProduct) {
Product product = new Product();
BeanUtils.copyProperties(upProduct, product);
productService.update(product);
return ApiRestResponse.success();
}
1
2
3
4
5
6
7
2
3
4
5
6
7
# service
同名且不同id
@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); } }
1
2
3
4
5
6
7
8
9
10
11
12
# 删除商品
controller
@DeleteMapping("/admin/product/delete")
public ApiRestResponse delete(int id) {
productService.delete(id);
return ApiRestResponse.success();
}
1
2
3
4
5
2
3
4
5
service
@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);
}
}
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
# 批量上下架
- mybatis 遍历list
- where 语句拼接
# mapper
跟mybatis相关需要加入注解的名字@Param
int batchUpdateSellStatus(@Param("ids") Integer[] ids, @Param("status") Integer status);
1
sql mapper
<update id="batchUpdateSellStatus">
update imooc_mall_product
set status = #{status}
where id in
<foreach collection="ids" open="(" close=")" item="id" separator=",">
#{id}
</foreach>
</update>
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
# SQL理解
使用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)
1
2
3
4
5
6
7
更新多个值的话
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)
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
# 商品列表
- 排序功能
- mybatis pagehelper
- 枚举:order by
# service
- 新建req类
- 新建query类
上次更新: 2022/06/05, 20:31:36