章节感悟:
1.jpa的使用,分页,之前写过的jpa的使用方法需要拿出来多看看
2.枚举类型的使用
3.api的规范以及使用方式
4.组成一个json类型对象返回给前台
5.设置url路径
6.序列化前端和数据库的映射之间的异同
7.提取出ResultVOUtils工具类的使用,resultful接口实现前后端对应
8.设置本机Ip和域名,虚拟机Ip和域名,以及nginx的使用
买家端商品
Dao层设计
1.创建实体类ProductInfo
2.创建持久层ProductInfoRepository接口
关于jpa的各种操作可以查看之前的博客,jpa的使用
3.单元测试
Service层设计
1.创建接口ProductInfoService,接口中声明几个方法
/** * 查找一件商品信息 * @param productId * @return */ ProductInfo findOne(String productId); /** * 查询所有在架商品列表 * @return */ ListfindUpAll(); /** * 查找所有商品分页显示 * @param pageable * @return */ Page findAll(Pageable pageable); /** * 保存一个商品信息 * @param productInfo * @return */ ProductInfo save(ProductInfo productInfo);
这里运用到了jpa自带的分页
2.创建ProductInfoServiceImpl类,实现接口
3.创建一个productStatus枚举类型,即上架(0),下架(1),包含进来
@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; } }
然后在service中插入状态时则可以,如下写这样
productInfoRepository.findByProductStatus(ProductStatusEnum.UP.getCode());
视频中用pageRequest来创建pageable对象,IDEA自动检查出了过时提醒
PageRequest request = PageRequest.of(0, 2);
Controller层设计
1.前端设计api:这个api是前端给后端的,需求如下:
商品列表 GET /sell/buyer/product/list 参数 无 返回 { "code": 0, "msg": "成功", "data": [ { "name": "热榜", "type": 1, "foods": [ { "id": "123456", "name": "皮蛋粥", "price": 1.2, "description": "好吃的皮蛋粥", "icon": "http://xxx.com", } ] }, { "name": "好吃的", "type": 2, "foods": [ { "id": "123457", "name": "慕斯蛋糕", "price": 10.9, "description": "美味爽口", "icon": "http://xxx.com", } ] } ] }
开发的时候基本都是后端定义api,这里的api是前端定义的,有get请求,有返回值
2.创建一个BuyerProductController
打上@Controller和路径@RequestMapping(“/buyer/product”)
然后在application.yml中配置项目上下文路径名:
server:
servlet:
context-path: /sell
3.根据分析,返回的数据中应该包含三个对象
4.创建一个VO(viewObject)包,约定返回前端的类都使用这个包下面的东西
为什么不用原有的dataObject类呢?因为原有的DataObject类中包含很多隐私,比如库存量之内的,保密所以重新创建类。
ResultVo类,这里我们是用了泛型,因为这个具体内容可能是很多种类型
@Data public class ResultVO{ /** 错误码 */ private Integer code; /** 提示信息 */ private String msg; /** 具体内容 */ private T data; }
ProductVo类,这里的@JsonProperty,指的是序列化之后传到前台是标签中的名字
/** * 商品类目 * @author Xiong YuSong * 2019/1/17 17:56 */ @Data public class ProductVO { @JsonProperty("name") private String categoryName; @JsonProperty("type") private Integer categoryType; @JsonProperty("foods") private ListproductInfoVOList; }
ProductInfoVO类,原有的DataObject类中包含很多隐私,比如库存量之内的,保密所以重新创建类.
/** * 商品详情 * @author Xiong YuSong * 2019/1/17 17:56 */ @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; }
Controller中操作一下可以显示成下图:
@GetMapping("/list") @ResponseBody public ResultVO list(){ ResultVO resultVO = new ResultVO(); resultVO.setCode(0); resultVO.setMsg("成功"); ProductVO productVO = new ProductVO(); ProductInfoVO productInfoVO = new ProductInfoVO(); productVO.setProductInfoVOList(Arrays.asList(productInfoVO)); resultVO.setData(Arrays.asList(productVO)); return resultVO; }
5.将这些类组装成api中需求的json格式,并且只查询数据库一次。进行组装的时候可以用算法减少时间复杂度。
1)查询所有商品
2)通过商品查询响应的类目
3)拼装
@Autowired private ProductInfoServiceImpl productInfoService; @Autowired private ProductCategoryServiceImpl productCategoryService; @GetMapping("/list") @ResponseBody public ResultVO list() { // 1)查询所有上架商品 ListproductInfoList = productInfoService.findUpAll(); // 2)通过商品查询响应的类目 List categoryTypeList = productInfoList.stream().map(x -> x.getCategoryType()).collect(Collectors.toList()); List productCategoryList = productCategoryService.findByCategoryTypeIn(categoryTypeList); // 3)拼装成对应的json List productVOList = new ArrayList<>(); for(ProductCategory productCategory:productCategoryList){ ProductVO productVO = new ProductVO(); productVO.setCategoryName(productCategory.getCategoryName()); productVO.setCategoryType(productCategory.getCategoryType()); List productInfoVOList = new ArrayList<>(); for(ProductInfo productInfo:productInfoList){ if(productCategory.getCategoryType().equals(productInfo.getCategoryType()) ){ ProductInfoVO productInfoVO = new ProductInfoVO(); BeanUtils.copyProperties(productInfo,productInfoVO); productInfoVOList.add(productInfoVO); } } productVO.setProductInfoVOList(productInfoVOList); productVOList.add(productVO); } ResultVO resultVO = new ResultVO(); resultVO.setCode(0); resultVO.setMsg("成功"); resultVO.setData(productVOList); return resultVO; }
6.封装一个返回的工具类ResultVOUtils
public class ResultVOUtils { public static ResultVO success(Object object){ ResultVO resultVO = new ResultVO(); resultVO.setData(object); resultVO.setMsg("成功"); resultVO.setCode(0); return resultVO; } public static ResultVO success(){ return success(null); } public static ResultVO error(Integer code ,String msg){ ResultVO resultVO = new ResultVO(); resultVO.setMsg(msg); resultVO.setCode(code); return resultVO; } }
7.设置虚拟机的url的域名,ip地址映射,本地域名和本地IP地址映射
此时请求的是虚拟机的地址,但是后端业务是在本地地址,所以无法获取数据,修改虚拟机中的nginx配置(Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,并在一个BSD-like 协议下发行。其特点是占有内存少,并发能力强,事实上nginx的并发能力确实在同类型的网页服务器中表现较好。)
修改对应IP地址以及域名
修改本机对应域名
document.cookie="openid=aaaaa"