zoukankan      html  css  js  c++  java
  • 微信点餐系统(一)买家商品列表

    一、开发环境

    • JDK 1.8
    • MySQL 5.7
    • springboot 2.2.4
    • mybatis 1.1.1
    • redis 3.2.8

    可能有的人的MySQL版本不到5.7,在下面创建数据库的时候可能会报错。我的解决办法使用Docker创建一个合适版本的MySQL容器,参考:使用docker创建MySQL容器,并在springboot中使用

    二、开发工具

    • IDEA
    • Notepad++
    • VirtualBox
    • SQLyog

     三、项目简单分析

    该项目的角色主要分为买家端、买家端。买家端主要实现的功能有商品的查询和订单查询、创建、取消等,而卖家端主要是对订单的管理、商品的管理、类目的管理等。

    四、在数据库中创建四张数据表

    创建一个sell数据库,并在其中创建四张数据表,创建语句如下:

     1 CREATE TABLE product_info(
     2      product_id VARCHAR(32) NOT NULL,
     3      product_name VARCHAR(64) NOT NULL COMMENT "商品名称",
     4      product_price DECIMAL(8,2) NOT NULL COMMENT "单价",
     5      product_stock INT NOT NULL COMMENT "库存",
     6      product_description VARCHAR(64) COMMENT "描述",
     7      product_icon VARCHAR(512) COMMENT "小图",
     8      category_type INT NOT NULL COMMENT "类目编号",
     9      product_status TINYINT(3),
    10      create_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT "创建时间",
    11      update_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT "修改时间",
    12      PRIMARY KEY(product_id)
    13 ) COMMENT "商品表";
    14 
    15 CREATE TABLE product_category(
    16      category_id INT NOT NULL AUTO_INCREMENT,
    17      category_name VARCHAR(64) NOT NULL COMMENT '类目名称',
    18      category_type INT NOT NULL COMMENT '类目编号',
    19      create_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
    20      update_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
    21      PRIMARY KEY (category_id),
    22      UNIQUE KEY uqe_category_type (category_type)
    23 ) COMMENT '类目表';
    24 
    25 CREATE TABLE order_master (
    26      order_id VARCHAR(32) NOT NULL,
    27      buyer_name VARCHAR(32) NOT NULL COMMENT '买家名字',
    28      buyer_phone VARCHAR(32) NOT NULL COMMENT '买家电话',
    29      buyer_address VARCHAR(128) NOT NULL COMMENT '买家地址',
    30      buyer_openid VARCHAR(64) NOT NULL COMMENT '买家微信openid',
    31      order_amount DECIMAL(8,2) NOT NULL COMMENT '订单总金额',
    32      order_status TINYINT(3) NOT NULL DEFAULT 0 COMMENT '订单状态,默认0新下单',
    33      pay_status TINYINT(3) NOT NULL DEFAULT 0 COMMENT '支付状态,默认0未支付',
    34      create_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
    35      update_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
    36      PRIMARY KEY (order_id),
    37      KEY idx_buyer_openid (buyer_openid)
    38 ) COMMENT '订单表';
    39 
    40 CREATE TABLE order_detail (
    41      detail_id VARCHAR(32) NOT NULL,
    42      order_id VARCHAR(32) NOT NULL,
    43      product_id VARCHAR(32) NOT NULL,
    44      product_name VARCHAR(64) NOT NULL COMMENT '商品名称',
    45      product_price DECIMAL(8,2) NOT NULL COMMENT '商品价格',
    46      product_quantity INT NOT NULL COMMENT '商品数量',
    47      product_icon VARCHAR(512) COMMENT '商品小图',
    48      create_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
    49      update_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
    50      PRIMARY KEY (detail_id),
    51      KEY idx_order_id (order_id)
    52 ) COMMENT '订单详情表';
    View Code

    还差一张买家信息表,但是暂时还用不到就没创建。本文主要是买家商品list的实现就先介绍其中两张,product_category是商品的类目表,product_info是商品信息表。

     五.根据API文档在vo包下创建需要返回数据的类

    商品列表的API文档如下:

     1 ###商品列表
     2 
     3 ```
     4 GET /sell/buyer/product/list
     5 ```
     6 
     7 参数
     8 
     9 ```
    10 11 ```
    12 
    13 返回
    14 
    15 ```
    16 {
    17     "code": 0,
    18     "msg": "成功",
    19     "data": [
    20         {
    21             "name": "热榜",
    22             "type": 1,
    23             "foods": [
    24                 {
    25                     "id": "123456",
    26                     "name": "皮蛋粥",
    27                     "price": 1.2,
    28                     "description": "好吃的皮蛋粥",
    29                     "icon": "http://xxx.com",
    30                 }
    31             ]
    32         },
    33         {
    34             "name": "好吃的",
    35             "type": 2,
    36             "foods": [
    37                 {
    38                     "id": "123457",
    39                     "name": "慕斯蛋糕",
    40                     "price": 10.9,
    41                     "description": "美味爽口",
    42                     "icon": "http://xxx.com",
    43                 }
    44             ]
    45         }
    46     ]
    47 }
    48 ```

    根据商品列表文档可知需要返回数据最外层有"code","msg","data"字段,由于各个API"data"内内容不一致,将"data"类型指定为泛型T

    因此创建一个ResultVO类

     1 package club.nipengfei.VO;
     2 
     3 import lombok.Data;
     4 
     5 @Data
     6 public class ResultVO<T> {
     7 
     8     /** 错误码 */
     9     private Integer code;
    10 
    11     /** 提示信息 */
    12     private String msg;
    13 
    14     /** 具体内容 */
    15     private T data;
    16 
    17 }

    根据上述的文档可知"data"内是一个列表,其中一个元素的"name"表示"category_name","type"表示"category_type","foods"表示商品信息列表。

    根据这些字段在vo包下创建一个ProductVO类。@Data注解:lombok插件的一个注解自动生成get,set等方法。@JsonProperty注解:可以让返回前端例如"categoryName"变成"name",如果字段直接使用"name"不能方便获取该字段含义。

     1 package club.nipengfei.VO;
     2 
     3 import com.fasterxml.jackson.annotation.JsonProperty;
     4 import lombok.Data;
     5 
     6 import java.util.List;
     7 
     8 /**
     9  * 商品(包含类目)
    10  */
    11 @Data
    12 public class ProductVO {
    13 
    14     @JsonProperty("name")
    15     private String categoryName;
    16 
    17     @JsonProperty("type")
    18     private Integer categoryType;
    19 
    20     @JsonProperty("foods")
    21     private List<ProductInfoVO> productInfoVOList;
    22 
    23 }

    "foods"列表中表示属于该类目"category"的商品,使用ProductInfoVO类封装。类型BigDecimal对应数据表中的"DECIMAL"一般钱都用这个类型。

     1 package club.nipengfei.VO;
     2 
     3 import com.fasterxml.jackson.annotation.JsonProperty;
     4 import lombok.Data;
     5 
     6 import java.math.BigDecimal;
     7 
     8 /**
     9  * 商品详情
    10  */
    11 @Data
    12 public class ProductInfoVO {
    13 
    14     @JsonProperty("id")
    15     private String productId;
    16 
    17     @JsonProperty("name")
    18     private String productName;
    19 
    20     @JsonProperty("price")
    21     private BigDecimal productPrice;
    22 
    23     @JsonProperty("description")
    24     private String productDescription;
    25 
    26     @JsonProperty("icon")
    27     private String productIcon;
    28 }

    六、开发repository层(dao层)

    在这之前需要根据数据库中的数据表建立相应映射类,ProductCategory类、ProductInfo类。

     1 package club.nipengfei.dataobject;
     2 
     3 import lombok.Data;
     4 
     5 import java.util.Date;
     6 
     7 /**
     8  * 类目
     9  */
    10 @Data
    11 public class ProductCategory {
    12 
    13     /**
    14      * 类目id
    15      */
    16     private Integer category_id;
    17 
    18     /**
    19      * 类目名字
    20      */
    21     private String category_name;
    22 
    23     /**
    24      * 类目编号
    25      */
    26     private Integer category_type;
    27 
    28     private Date create_time;
    29 
    30     private Date update_time;
    31 
    32 }
    View Code
     1 package club.nipengfei.dataobject;
     2 
     3 import lombok.Data;
     4 
     5 import java.math.BigDecimal;
     6 
     7 @Data
     8 public class ProductInfo {
     9 
    10     private String product_id;
    11 
    12     private String product_name;
    13 
    14     private BigDecimal product_price;
    15 
    16     private Integer product_stock;
    17 
    18     private String product_description;
    19 
    20     private String product_icon;
    21 
    22     /** 状态,0正常 1下架*/
    23     private Integer product_status;
    24 
    25     /** 类目编号*/
    26     private Integer category_type;
    27 }
    View Code

    在pom文件中引入相应依赖

            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>1.1.1</version>
            </dependency>
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
            </dependency>
    View Code

    并在配置文件中配置数据库的信息

    1 spring.datasource.url=jdbc:mysql://192.168.1.199/sell?characterEncoding=utf-8&useSSL=FALSE
    2 spring.datasource.username=root
    3 spring.datasource.password=123456
    View Code

     在ProductInfoRepository接口内写一个findUpAll抽象方法,将product_info表中上架的商品全部查出来,放入List<ProductInfo>中。然后在ProductCategoryRepository接口中写一个findByCategoryTypeIn抽象方法,根据List<Integer>参数查询出List<ProductCategory>。

    @Mapper注解会将注解的接口交给Mybatis处理,如果觉得麻烦可以在启动类上加上@MapperScan("club.nipengfei.repository")代替,该注解可以自动扫描repository包下的类

    @Repository注解将其交给spring处理,自动注册为spring bean

     1 package club.nipengfei.repository;
     2 
     3 import club.nipengfei.dataobject.ProductInfo;
     4 import com.github.pagehelper.Page;
     5 import org.apache.ibatis.annotations.Insert;
     6 import org.apache.ibatis.annotations.Mapper;
     7 import org.apache.ibatis.annotations.Select;
     8 import org.apache.ibatis.annotations.Update;
     9 import org.springframework.stereotype.Repository;
    10 
    11 import java.util.List;
    12 
    13 @Repository
    14 @Mapper
    15 public interface ProductInfoRepository {
    16 
    17     @Select("select * from product_info where product_status=0")
    18     List<ProductInfo> findUpAll();
    19 
    20 }

    下面的select语句中使用了mybatis的动态SQL,参考:https://mybatis.org/mybatis-3/zh/dynamic-sql.html

    注意在注解中使用动态SQL需要使用<script>

     1 package club.nipengfei.repository;
     2 
     3 import club.nipengfei.dataobject.ProductCategory;
     4 import org.apache.ibatis.annotations.Insert;
     5 import org.apache.ibatis.annotations.Mapper;
     6 import org.apache.ibatis.annotations.Param;
     7 import org.apache.ibatis.annotations.Select;
     8 import org.springframework.stereotype.Repository;
     9 
    10 import java.util.List;
    11 
    12 @Mapper
    13 @Repository
    14 public interface ProductCategoryRepository {
    15 
    16 
    17     @Select("<script>select * from product_category " +
    18             "<where>" +
    19             "<if test='list != null and list.size()>0' >"+
    20             "<foreach collection='list' open='and category_type in (' close=')' item='id' separator=','> #{id}</foreach>"+
    21             "</if>"+
    22             "</where>"+
    23             "</script>")
    24     List<ProductCategory> findByCategoryTypeIn(@Param("list") List<Integer> list);
    25 }

    七、service层开发

    @Service注解与上面的@Repository一样将其注册为spring bean

    @Autowired注解,bean的自动注入

     1 package club.nipengfei.service;
     2 
     3 import club.nipengfei.dataobject.ProductInfo;
     4 import club.nipengfei.dto.CartDTO;
     5 import com.github.pagehelper.Page;
     6 
     7 import java.util.List;
     8 
     9 public interface ProductService {
    10 
    11     /**
    12      * 查询所有在架商品列表
    13      * @return
    14      */
    15     List<ProductInfo> findUpAll();
    16 
    17 }
    View Code
     1 package club.nipengfei.service.impl;
     2 
     3 import club.nipengfei.dataobject.ProductInfo;
     4 import club.nipengfei.dto.CartDTO;
     5 import club.nipengfei.enums.ResultEnum;
     6 import club.nipengfei.exception.SellException;
     7 import club.nipengfei.repository.ProductInfoRepository;
     8 import club.nipengfei.service.ProductService;
     9 import com.github.pagehelper.Page;
    10 import org.springframework.beans.factory.annotation.Autowired;
    11 import org.springframework.stereotype.Service;
    12 import org.springframework.transaction.annotation.Transactional;
    13 
    14 import java.util.List;
    15 
    16 @Service
    17 public class ProductServiceImpl implements ProductService {
    18 
    19     @Autowired
    20     private ProductInfoRepository repository;
    21 
    22     @Override
    23     public List<ProductInfo> findUpAll() {
    24         return repository.findUpAll();
    25     }
    26 
    27 }
    View Code
     1 package club.nipengfei.service;
     2 
     3 import club.nipengfei.dataobject.ProductCategory;
     4 
     5 import java.util.List;
     6 
     7 public interface CategoryService {
     8 
     9     List<ProductCategory> findByCategoryTypeIn(List<Integer> categoryTypeList);
    10 
    11 }
    View Code
     1 package club.nipengfei.service.impl;
     2 
     3 import club.nipengfei.dataobject.ProductCategory;
     4 import club.nipengfei.repository.ProductCategoryRepository;
     5 import club.nipengfei.service.CategoryService;
     6 import org.springframework.beans.factory.annotation.Autowired;
     7 import org.springframework.stereotype.Service;
     8 
     9 import java.util.List;
    10 
    11 @Service
    12 public class CategoryServiceImpl implements CategoryService {
    13 
    14     @Autowired
    15     private ProductCategoryRepository repository;
    16 
    17     @Override
    18     public List<ProductCategory> findByCategoryTypeIn(List<Integer> categoryTypeList) {
    19         return repository.findByCategoryTypeIn(categoryTypeList);
    20     }
    21 
    22 }
    View Code

    八、controller层的开发

    根据API文档请求方法和路径,在配置文件中写入一个项目路径"/sell",新建一个BuyerProductController类在这上面加上注解@RequestMapping指定值为"/buyer/product",在list方法上使用@GetMapping注解,指定值为"list"。@RestController注解@ResponseBody和@Controller的组合注解,@ResponseBody注解是返回json,@Controller注解处理http请求。

    1 server.servlet.context-path=/sell
     1 package club.nipengfei.controller;
     2 
     3 import club.nipengfei.VO.ProductInfoVO;
     4 import club.nipengfei.VO.ProductVO;
     5 import club.nipengfei.VO.ResultVO;
     6 import club.nipengfei.dataobject.ProductCategory;
     7 import club.nipengfei.dataobject.ProductInfo;
     8 import club.nipengfei.service.CategoryService;
     9 import club.nipengfei.service.ProductService;
    10 import club.nipengfei.utils.ResultVOUtil;
    11 import org.springframework.beans.BeanUtils;
    12 import org.springframework.beans.factory.annotation.Autowired;
    13 import org.springframework.web.bind.annotation.GetMapping;
    14 import org.springframework.web.bind.annotation.RequestMapping;
    15 import org.springframework.web.bind.annotation.RestController;
    16 
    17 import java.util.ArrayList;
    18 import java.util.Arrays;
    19 import java.util.List;
    20 
    21 @RestController
    22 @RequestMapping("/buyer/product")
    23 public class BuyerProductController {
    24 
    25     @Autowired
    26     private ProductService productService;
    27 
    28     @Autowired
    29     private CategoryService categoryService;
    30 
    31 
    32     @GetMapping("/list")
    33     public ResultVO list() {
    34 
    35         // 1.查询所有上架商品
    36         List<ProductInfo> productInfoList = productService.findUpAll();
    37 
    38         // 2.查询类目(一次查询)
    39         List<Integer> categoryTypeList = new ArrayList<>();
    40         for (ProductInfo productInfo : productInfoList) {
    41             categoryTypeList.add(productInfo.getCategory_type());
    42         }
    43         /** 当categoryTypeList为空时,即商品都没有上架,程序会报错 */
    44         List<ProductCategory> productCategoryList = categoryService.findByCategoryTypeIn( categoryTypeList);
    45 
    46         // 3.数据拼接
    47         List<ProductVO> productVOList = new ArrayList<>();
    48         for (ProductCategory productCategory : productCategoryList) {
    49             ProductVO productVO = new ProductVO();
    50             productVO.setCategoryType(productCategory.getCategory_type());
    51             productVO.setCategoryName(productCategory.getCategory_name());
    52 
    53             List<ProductInfoVO> productInfoVOList = new ArrayList<>();
    54             for (ProductInfo productInfo : productInfoList) {
    55                 if (productInfo.getCategory_type().equals(productCategory.getCategory_type())){
    56                     ProductInfoVO productInfoVO = new ProductInfoVO();
    57 
    58                     // BeanUtils.copyProperties(productInfo,productInfoVO);
    59                     // 由于我的productInfo和productInfoVO的字段名不一致,不能使用上面的工具,而使用下面的
    60                     productInfoVO.setProductId(productInfo.getProduct_id());
    61                     productInfoVO.setProductName(productInfo.getProduct_name());
    62                     productInfoVO.setProductPrice(productInfo.getProduct_price());
    63                     productInfoVO.setProductDescription(productInfo.getProduct_description());
    64                     productInfoVO.setProductIcon(productInfo.getProduct_icon());
    65 
    66                     productInfoVOList.add(productInfoVO);
    67                 }
    68             }
    69             productVO.setProductInfoVOList(productInfoVOList);
    70             productVOList.add(productVO);
    71         }
    72 
    73         return ResultVOUtil.success(productVOList);
    74     }
    75 }
    View Code
     1 package club.nipengfei.utils;
     2 
     3 import club.nipengfei.VO.ResultVO;
     4 
     5 public class ResultVOUtil {
     6 
     7     public static ResultVO success(Object object){
     8         ResultVO resultVO = new ResultVO();
     9         resultVO.setData(object);
    10         resultVO.setCode(0);
    11         resultVO.setMsg("成功");
    12         return resultVO;
    13     }
    14 
    15     public static ResultVO success(){
    16         return success(null);
    17     }
    18 
    19     public static ResultVO error(Integer code,String msg){
    20         ResultVO resultVO = new ResultVO();
    21         resultVO.setCode(code);
    22         resultVO.setMsg(msg);
    23         return resultVO;
    24     }
    25 }
    View Code

    在本地浏览器或者Postman中输入http://127.0.0.1:8080/sell/buyer/product/list,就可以发现返回json格式与API文档一致

     九、存在的问题

    @Mapper,@Repository,@Autowired,@RestController等注解具体是怎么工作的还是不太了解。mybatis中动态sql使用有点困难。

  • 相关阅读:
    python--迭代器与生成器
    python--内置函数
    python--递归、二分查找算法
    【转】Appium根据xpath获取控件实例随笔
    【转】Appium基于安卓的各种FindElement的控件定位方法实践
    Robot Framework + appium 启动手机浏览器的两个方法(1)
    文件夹添加右键DOS快捷入口
    MacOS10.9平台配置Appium+Java环境
    Windows平台配置Appium+Java环境
    java 字符串反转
  • 原文地址:https://www.cnblogs.com/qzwl/p/12409993.html
Copyright © 2011-2022 走看看