第三课 SpringBoot微信点餐系统买家商品设计
tags:
- Java
- 慕课网
categories:
- DAO层开发
- service层 开发
- 拼接json
- 取数据
- api
文章目录
第一节 商品DAO层设计与开发
1.1 数据库映射成对象
- src\main\java\com\qnhyn\dataobject\ProductInfo.java
package com.qnhyn.dataobject;
import lombok.Data;
import javax.persistence.Entity;
import javax.persistence.Id;
import java.math.BigDecimal;
@Entity
@Data
public class ProductInfo {
@Id
private String productId;
/** 名字 **/
private String productName;
/** 单价 **/
private BigDecimal productPrice;
/** 库存 **/
private Integer productStock;
/** 描述 **/
private String productDescription;
/** 商品小图 **/
private String productIcon;
/** 商品状态 0正常1下架. **/
private Integer productStatus;
/** 类目编号 **/
private Integer categoryType;
}
1.2 DAO层
- sell\src\main\java\com\qnhyn\repository\ProductInfoRepository.java
package com.qnhyn.repository;
import com.qnhyn.dataobject.ProductInfo;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;
public interface ProductInfoRepository extends JpaRepository<ProductInfo, String> {
List<ProductInfo> findByProductStatus(Integer productStatus);
}
1.3 测试一下是否成功
- 右键 GO TO test
package com.qnhyn.repository;
import com.qnhyn.dataobject.ProductInfo;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.math.BigDecimal;
import java.util.List;
import static org.junit.jupiter.api.Assertions.*;
@RunWith(SpringRunner.class)
@SpringBootTest
public class ProductInfoRepositoryTest {
@Autowired
private ProductInfoRepository repository;
@Test
public void saveTest() {
ProductInfo productInfo = new ProductInfo();
productInfo.setProductId("123456");
productInfo.setProductName("皮蛋粥");
productInfo.setProductPrice(new BigDecimal(3.2));
productInfo.setProductStock(100);
productInfo.setProductDescription("很好喝的粥");
productInfo.setProductIcon("http://xxx.jpg");
productInfo.setProductStatus(0);
productInfo.setCategoryType(2);
repository.save(productInfo);
}
@Test
public void findByProductStatus() throws Exception {
List<ProductInfo> productInfoList = repository.findByProductStatus(0);
Assert.assertNotEquals(0, productInfoList.size());
}
}
第二节 商品Service层设计与开发
2.1 创建service接口
- sell\src\main\java\com\qnhyn\service\ProductService.java
package com.qnhyn.service;
import com.qnhyn.dataobject.ProductInfo;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import java.util.List;
public interface ProductService {
ProductInfo findOne(String productId);
/** 查询所有在架的商品列表 **/
List<ProductInfo> findUpAll();
/** 查询所有的商品列表 这里注意选择第二个**/
Page<ProductInfo> findAll(Pageable pageable);
ProductInfo save(ProductInfo productInfo);
// 加库存
// 减库存
}
2.2 service接口实现类
- sell\src\main\java\com\qnhyn\service\impl\ProductServiceImpl.java
package com.qnhyn.service.impl;
import com.qnhyn.dataobject.ProductInfo;
import com.qnhyn.enums.ProductStatusEnum;
import com.qnhyn.repository.ProductInfoRepository;
import com.qnhyn.service.ProductService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class ProductServiceImpl implements ProductService {
@Autowired
private ProductInfoRepository repository;
@Override
public ProductInfo findOne(String productId) {
return repository.findById(productId).orElse(null);
}
@Override
public List<ProductInfo> findUpAll() {
/** 代码中老是有0或1这种东西 可读性不好 用枚举解决 **/
return repository.findByProductStatus(ProductStatusEnum.UP.getCode());
}
@Override
public Page<ProductInfo> findAll(Pageable pageable) {
return repository.findAll(pageable);
}
@Override
public ProductInfo save(ProductInfo productInfo) {
return repository.save(productInfo);
}
}
- 加枚举让代码中不直接出现数字。增加代码的可读性。创建sell\src\main\java\com\qnhyn\enums\ProductStatusEnum.java
package com.qnhyn.enums;
import lombok.Getter;
/** 商品状态 **/
@Getter
public enum ProductStatusEnum {
UP(0, "在架"),
DOWN(1, "下架")
;
private Integer code;
private String message;
ProductStatusEnum(Integer code, String message) {
this.code = code;
this.message = message;
}
}
2.3 service接口实现类测试
- sell\src\test\java\com\qnhyn\repository\ProductInfoRepositoryTest.java
package com.qnhyn.repository;
import com.qnhyn.dataobject.ProductInfo;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.math.BigDecimal;
import java.util.List;
import static org.junit.jupiter.api.Assertions.*;
@RunWith(SpringRunner.class)
@SpringBootTest
public class ProductInfoRepositoryTest {
@Autowired
private ProductInfoRepository repository;
@Test
public void saveTest() {
ProductInfo productInfo = new ProductInfo();
productInfo.setProductId("123456");
productInfo.setProductName("皮蛋粥");
productInfo.setProductPrice(new BigDecimal(3.2));
productInfo.setProductStock(100);
productInfo.setProductDescription("很好喝的粥");
productInfo.setProductIcon("http://xxx.jpg");
productInfo.setProductStatus(0);
productInfo.setCategoryType(2);
repository.save(productInfo);
}
@Test
public void findByProductStatus() throws Exception {
List<ProductInfo> productInfoList = repository.findByProductStatus(0);
Assert.assertNotEquals(0, productInfoList.size());
}
}
第三节 买家商品api开发
3.1 设置context path
- 配置文件中加入下面。
# 之前版本
server:
context-path: /sell
# 比较新的版本新的版本在2.0以上
server:
servlet:
context-path: /sell
3.2 设置路由
- 写一个控制器。sell\src\main\java\com\qnhyn\controller\BuyerProductController.java
- 注意路由。配合上面配置访问
package com.qnhyn.controller;
import com.qnhyn.VO.ProductInfoVO;
import com.qnhyn.VO.ProductVO;
import com.qnhyn.VO.ResultVO;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Arrays;
@RestController
@RequestMapping("/buyer/product")
public class BuyerProductController {
@GetMapping("/list")
public ResultVO list(){
ResultVO resultVO = new ResultVO();
ProductVO productVO = new ProductVO();
ProductInfoVO productInfoVO = new ProductInfoVO();
productVO.setProductInfoVOList(Arrays.asList(productInfoVO));
resultVO.setData(Arrays.asList(productVO));
resultVO.setCode(0);
resultVO.setMsg("成功");
return resultVO;
}
}
3.3 VO成为view object
- 用来写希望返回给前端的json对象。用作json对象拼接,全写在VO文件夹下,层层嵌套的json对象。
- 新建文件夹VO,写下面三个vo
- ResultVO
- ProductVO
- ProductInfoVO
package com.qnhyn.VO;
import lombok.Data;
/**
* http请求返回的最外层的对象
*/
@Data
public class ResultVO<T> {
/** 错误码 **/
private Integer code;
/** 提示信息 **/
private String msg;
/** 具体内容 **/
private T data;
}
package com.qnhyn.VO;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import java.util.List;
/**
* 商品包含类目
*/
@Data
public class ProductVO {
/** 这个注解可以给字段重命名为返回给前端的名称 **/
@JsonProperty("name")
private String categoryName;
@JsonProperty("type")
private Integer categoryType;
@JsonProperty("foods")
private List<ProductInfoVO> productInfoVOList;
}
package com.qnhyn.VO;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import java.math.BigDecimal;
/**
* 商品详情
* 这里不用dataobject下的ProductInfo
* 因为字段太多我们只返回前端需要的字段
* 为了隐私安全 所以新建一个类
*/
@Data
public class ProductInfoVO {
@JsonProperty("id")
private String productId;
@JsonProperty("name")
private String productName;
@JsonProperty("price")
private BigDecimal productPrice;
@JsonProperty("description")
private String productDescription;
@JsonProperty("icon")
private String productIcon;
}
- 拼接出数据。http://127.0.0.1:8080/sell/buyer/product/list
{
"code": 0,
"msg": "成功",
"data": [{
"name": null,
"type": null,
"foods": [{
"id": null,
"name": null,
"price": null,
"description": null,
"icon": null
}]
}]
}
3.3 把数据库数据填充到上面格式
- sell\src\main\java\com\qnhyn\controller\BuyerProductController.java
package com.qnhyn.controller;
import com.qnhyn.VO.ProductInfoVO;
import com.qnhyn.VO.ProductVO;
import com.qnhyn.VO.ResultVO;
import com.qnhyn.dataobject.ProductCategory;
import com.qnhyn.dataobject.ProductInfo;
import com.qnhyn.service.CategoryService;
import com.qnhyn.service.ProductService;
import com.qnhyn.utils.ResultVOUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
@RestController
@RequestMapping("/buyer/product")
public class BuyerProductController {
@Autowired
private ProductService productService;
@Autowired
private CategoryService categoryService;
@GetMapping("/list")
public ResultVO list(){
// 1. 查询所有的上架商品
List<ProductInfo> productInfoList = productService.findUpAll();
// 2. 查询类目(一次性查询(绝对不能根据商品遍历查询类目,性能会极大损失的))
List<Integer> categoryTypeList = new ArrayList<>();
for (ProductInfo productInfo : productInfoList){
categoryTypeList.add(productInfo.getCategoryType());
}
// 精简方法(java8特性, lambda)
// List<Integer> categoryTypeList = productInfoList.stream()
// .map(e -> e.getCategoryType())
// .collect(Collectors.toList());
List<ProductCategory> productCategoryList = categoryService.findByCategoryTypeIn(categoryTypeList);
// 3. 数据拼装
List<ProductVO> productVOList = new ArrayList<>();
for (ProductCategory productCategory: productCategoryList){
ProductVO productVO = new ProductVO();
productVO.setCategoryType(productCategory.getCategoryType());
productVO.setCategoryName(productCategory.getCategoryName());
List<ProductInfoVO> productInfoVOList = new ArrayList<>();
for(ProductInfo productInfo: productInfoList){
if(productInfo.getCategoryType().equals(productCategory.getCategoryType())){
ProductInfoVO productInfoVO = new ProductInfoVO();
// 可以把一个对象的值 复制到 另外一个对象中
BeanUtils.copyProperties(productInfo, productInfoVO);
// System.out.println(productInfoVO);
productInfoVOList.add(productInfoVO);
}
}
productVO.setProductInfoVOList(productInfoVOList);
productVOList.add(productVO);
}
return ResultVOUtil.success(productVOList);
}
}
- 新建文件sell\src\main\java\com\qnhyn\utils\ResultVOUtil.java。
package com.qnhyn.utils;
import com.qnhyn.VO.ResultVO;
public class ResultVOUtil {
public static ResultVO success(Object object){
ResultVO resultVO = new ResultVO();
resultVO.setCode(0);
resultVO.setMsg("成功");
return resultVO;
}
public static ResultVO success(){
return success(null);
}
public static ResultVO error(Integer code, String msg){
ResultVO resultVO = new ResultVO();
resultVO.setCode(code);
resultVO.setMsg(msg);
return resultVO;
}
}