一、买家端类目
1、创立实体类
首先创立实体类,这里先创立买家类目表的实体类。
@Data@Entity@DynamicUpdatepublic class ProductCategory { //类目id @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer categoryId; //类目名称 private String categoryName; //类目品种 private Integer categoryType; //类目创立工夫 private Date createTime; //类目更新工夫 private Date updateTime; public ProductCategory(Integer categoryId, String categoryName, Integer categoryType) { this.categoryId = categoryId; this.categoryName = categoryName; this.categoryType = categoryType; } public ProductCategory() { } @Override public String toString() { return "ProductCategory{" + "categoryId=" + categoryId + ", categoryName='" + categoryName + '\'' + ", categoryType=" + categoryType + ", createTime=" + createTime + ", updateTime=" + updateTime + '}'; }}
这里留神类名及属性名要与数据库表一一对应,这个类中为了晓得创立及更新工夫,退出了工夫参数,然而不是手动上传,而是自动更新的,所以要加上注解@DynamicUpdate。
所以理论须要写的只有两个一个类目名称、一个类目类型,主键自增,写好这三个参数的构造方法,加上Getter和Setter办法,toString办法,把他们用@Entity设置成实体类,在竹简上加上@Id,并且设置为自增。
2、创立dao并测试
Dao写成接口继承Jpa的接口。这样就能够间接应用Jpa中的办法了。
这里就要留神事实当中的业务场景了,查问类目类型,能够查问到所须要类型的List汇合了。(就相当于把所有类目都查出来,然而也可能只查一部分)
public interface ProductCategoryRepository extends JpaRepository<ProductCategory,Integer> { List<ProductCategory> findByCategoryTypeIn(List<Integer> categoryTypeList);}
测试。点击类目右键GO TO TEST间接生成测试方法,如果不及时测试,报错都不晓得是哪个环节有问题。
@RunWith(SpringRunner.class)@SpringBootTestpublic class ProductCategoryRepositoryTest { @Autowired private ProductCategoryRepository repository; //测试保留 @Test public void testSave(){ ProductCategory productCategory = new ProductCategory(); productCategory.setCategoryName("增肌必备"); productCategory.setCategoryType(3); ProductCategory pro = repository.save(productCategory); Assert.assertNotEquals(0,pro); } //测试查找一个 @Test public void testFind(){ ProductCategory productCategory = repository.findById(1).get(); Assert.assertNotNull(productCategory); } //测试更新 @Test public void testUpdate(){ ProductCategory productCategory = new ProductCategory(); productCategory.setCategoryId(8); productCategory.setCategoryName("丰胸必备"); productCategory.setCategoryType(6); ProductCategory pro = repository.save(productCategory); Assert.assertNotEquals(0,pro); } //测试查找多个 @Test public void testFindByCategoryTypeIn(){ List<Integer> categoryTypeList = new ArrayList<>(); categoryTypeList.add(2); categoryTypeList.add(3); categoryTypeList.add(4); categoryTypeList.add(5); List<ProductCategory> byCategoryTypeIn = repository.findByCategoryTypeIn(categoryTypeList); for (ProductCategory productCategory:byCategoryTypeIn){ System.out.println(productCategory); } }
3、买家端service层
这里就是业务相干了,查问所有类目用于卖家后盾操作,新增类目、更新类目同理,查问一条类目前面可用于显示所有商品等等,查问多条类目能够用于给买家展现以后有什么流动等等,如男生最爱,热销榜等等类目。
先写个service接口。
/** * 类目表的service层接口 */public interface ProductCategoryService { //查问一条 ProductCategory findOne(Integer categoryId); //查问所有 List<ProductCategory> findAll(); //查问多条 List<ProductCategory> findByCategoryTypeIn(List<Integer> categoryTypeList); //新增和更新 ProductCategory save(ProductCategory productCategory);}
再写其实现类。
@Service//类目表的service层实现类public class ProductCategoryServiceImpl implements ProductCategoryService { @Autowired private ProductCategoryRepository repository; @Override public ProductCategory findOne(Integer categoryId) { return repository.findById(categoryId).get(); } @Override public List<ProductCategory> findAll() { return repository.findAll(); } @Override public List<ProductCategory> findByCategoryTypeIn(List<Integer> categoryTypeList) { return repository.findByCategoryTypeIn(categoryTypeList); } @Override public ProductCategory save(ProductCategory productCategory) { return repository.save(productCategory); }}
最初进行测试。
@RunWith(SpringRunner.class)@SpringBootTestpublic class ProductCategoryRepositoryTest { @Autowired private ProductCategoryRepository repository; @Test public void testSave(){ ProductCategory productCategory = new ProductCategory(); productCategory.setCategoryName("增肌必备"); productCategory.setCategoryType(3); ProductCategory pro = repository.save(productCategory); Assert.assertNotEquals(0,pro); } @Test public void testFind(){ ProductCategory productCategory = repository.findById(1).get(); Assert.assertNotNull(productCategory); } @Test public void testUpdate(){ ProductCategory productCategory = new ProductCategory(); productCategory.setCategoryId(8); productCategory.setCategoryName("丰胸必备"); productCategory.setCategoryType(6); ProductCategory pro = repository.save(productCategory); Assert.assertNotEquals(0,pro); } @Test public void testFindByCategoryTypeIn(){ List<Integer> categoryTypeList = new ArrayList<>(); categoryTypeList.add(2); categoryTypeList.add(3); categoryTypeList.add(4); categoryTypeList.add(5); List<ProductCategory> byCategoryTypeIn = repository.findByCategoryTypeIn(categoryTypeList); for (ProductCategory productCategory:byCategoryTypeIn){ System.out.println(productCategory); } }}
二、买家端商品
1、创立实体类
买家端商品也一样,次要是商品的增删改查。
生成产品的实体类
@Data@Entitypublic class ProductInfo { //商品id @Id private String productId; //商品名称 private String productName; //商品价格 private BigDecimal productPrice; //商品库存 private Integer productStock; //商品形容 private String productDescription; //商品小图 private String productIcon; //商品类型 private Integer productStatus; //所属类目类型 private Integer categoryType; /*//创立工夫 private Date createTime; //更新工夫 private Date updateTime;*/}
因为它是String类型的id,所以不能自增。创立工夫和更新工夫先不写,加上@Entity注解和id。
2、创立dao并测试
而后就是写Dao测试。
public interface ProductInfoRepository extends JpaRepository<ProductInfo,String> { //查问上架的商品 List<ProductInfo> findByProductStatus(Integer productStatus);}
测试。
@RunWith(SpringRunner.class)@SpringBootTestpublic class ProductInfoRepositoryTest { @Autowired private ProductInfoRepository repository; @Test public void testSave(){ ProductInfo productInfo = new ProductInfo(); productInfo.setProductId("123458"); productInfo.setProductName("鱼翅炒饭"); productInfo.setProductPrice(new BigDecimal(100.00)); productInfo.setProductStock(12); productInfo.setProductDescription("鱼翅炒饭,尉迟炒的饭"); productInfo.setProductIcon("http://xxx.jpg"); productInfo.setCategoryType(3); ProductInfo prod = repository.save(productInfo); Assert.assertNotEquals(null,prod); } @Test public void findByProductStatus() { List<ProductInfo> productInfos = repository.findByProductStatus(2); productInfos.forEach(productInfo -> System.out.println(productInfo)); }}
3、买家端商品service层
接口。
public interface ProductInfoService { //查问一个 ProductInfo findOne(String productId); //查问所有的商品 Page<ProductInfo> findAll(Pageable pageable); //查问所有在架的商品 List<ProductInfo> findUpAll(); //保留 ProductInfo save(ProductInfo productInfo); //加库存 //减库存}
接口实现类。
@Servicepublic class ProductInfoServiceImpl implements ProductInfoService { @Autowired private ProductInfoRepository repository; @Override public ProductInfo findOne(String productId) { return repository.findById(productId).get(); } @Override public Page<ProductInfo> findAll(Pageable pageable) { return repository.findAll(pageable); } @Override public List<ProductInfo> findUpAll() { return repository.findByProductStatus(ProductStatusEnum.UP.getCode()); } @Override public ProductInfo save(ProductInfo productInfo) { return repository.save(productInfo); }}
测试方法。
@RunWith(SpringRunner.class)@SpringBootTestpublic class ProductInfoServiceImplTest { @Autowired private ProductInfoServiceImpl service; @Test public void findOne() { ProductInfo productInfo = service.findOne("123456"); Assert.assertEquals("123456",productInfo.getProductId()); } @Test public void findAll() { PageRequest request = PageRequest.of(0,2); Page<ProductInfo> productInfos = service.findAll(request); Assert.assertNotEquals(0,productInfos.getSize()); } @Test public void findUpAll() { List<ProductInfo> pr = service.findUpAll(); pr.forEach(productInfo -> System.out.println(productInfo)); } @Test public void save() { ProductInfo productInfo = new ProductInfo(); productInfo.setProductId("123459"); productInfo.setProductName("减肥餐"); productInfo.setProductPrice(new BigDecimal(20.9)); productInfo.setProductStock(100); productInfo.setProductDescription("减肥餐,一顿减10斤"); productInfo.setProductIcon("http://xxxxxxx.jpg"); productInfo.setProductStatus(0); productInfo.setCategoryType(0); ProductInfo productInfo1 = service.save(productInfo); Assert.assertNotEquals(null,productInfo1); }}
三、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", } ] } ]}
这里剖析一下,外层一个code、msg、还有一个data的数组。data中蕴含类目名称、类目类型、还有该类目下的所有商品、商品又包含id编号、名称、价格、形容和图片。所以依照这个写即可。
1、最外层
最外层也就是code、msg、data的数据。为了不便传输,创立一个返回前端的对象。这里如果一下子都写了太麻烦了,一层一层逻辑不好分清,所以先写个最外层ResultVO类(VO就是view object的简写)。
/** * http申请返回的最外层对象 */@Datapublic class ResultVO<T> { //code错误码 private Integer code; //msg private String msg; //对象 private T data;}
而后写个controller并拜访。
@RestController@RequestMapping("/buyer/product")public class BuyerProductController { @RequestMapping("/list") public ResultVO list(){ ResultVO resultVO = new ResultVO(); return resultVO; }}
因为api中说了要拜访/sell/buyer/product/list地址,controller中少了一层/sell,所以咱们在yaml中配置一下后面的门路。
spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver username: root password: 123456 url: jdbc:mysql://192.168.1.9:3306/sell?characterEncoding=utf-8&userSSL=false jpa: show-sql: trueserver: port: 8081 servlet: context-path: /sell #次要是配置这个
这样启动并测试。为了让浏览器解析数据为json格局能够下载相干插件。
2、中间层
这样最外层就有了,上面该写中间层了,看一下下面Json格局中间层是我的项目的类目层。
中间层是类目层。还是老规矩,写个ProductVo类。
/** * 其实是商品蕴含类目层 */@Datapublic class ProductVO { @JsonProperty("name") private String categoryName; @JsonProperty("type") private Integer categoryType; @JsonProperty("food") private List<ProductInfoVO> productInfoVOList;}
3、最内层
/** * 商品详情 */@Datapublic class ProductInfoVO { @JsonProperty("id") private String productId; @JsonProperty("name") private String productName; @JsonProperty("price") private BigDecimal productPrice; @JsonProperty private String productDescription; @JsonProperty("icon") private String productIcon;}
这样写完当前,把他们关联起来并测试。
原代码改良如下:增加了一些数据进行测试。
@RequestMapping("/list")public ResultVO list(){ ResultVO resultVO = new ResultVO(); ProductVO productVO = new ProductVO(); ProductInfoVO productInfoVO = new ProductInfoVO(); productInfoVO.setProductId("123456"); productInfoVO.setProductName("皮蛋瘦肉粥"); productInfoVO.setProductPrice(new BigDecimal(11.00)); productInfoVO.setProductDescription("赵谦孙李,粥无阵亡"); productInfoVO.setProductIcon("http:xxxx.jsp"); resultVO.setCode(0); resultVO.setMsg("胜利"); resultVO.setData(productVO); productVO.setCategoryName("热销榜"); productVO.setCategoryType(2); productVO.setProductInfoVOList(Arrays.asList(productInfoVO)); return resultVO;}
测试后果如下(忘了截图了,根本就是这个样子):
这样测试实现后阐明咱们能够通过这个进行传递json数据给前端了。
4、查询数据库传递给json对象
json的路线搭建好之后,就该传递真正的数据了,也就是把数据传递给controller。
@RestController@RequestMapping("/buyer/product")public class BuyerProductController { @Autowired private ProductInfoService productInfoService; @Autowired private ProductCategoryService productCategoryService; @RequestMapping("/list") public ResultVO list(){ //1、查问所有的上架商品 List<ProductInfo> productInfoUpAll = productInfoService.findUpAll(); //2、查问类目(要一次性查问) List<Integer> categoryTypeList = productInfoUpAll.stream().map(e -> e.getCategoryType()).collect(Collectors.toList()); List<ProductCategory> productCategoryList = productCategoryService.findByCategoryTypeIn(categoryTypeList); //3、数据拼装 List<ProductVO> productVOList = new ArrayList<>(); for (ProductCategory productCategory:productCategoryList){ ProductVO productVO = new ProductVO(); productVO.setCategoryName(productCategory.getCategoryName()); productVO.setCategoryType(productCategory.getCategoryType()); List<ProductInfoVO> productInfoVOList = new ArrayList<>(); for (ProductInfo productInfo:productInfoUpAll){ //上面这步要好好了解 if (productInfo.getCategoryType().equals(productCategory.getCategoryType())) { ProductInfoVO productInfoVO = new ProductInfoVO(); //productInfoVO.setProductId(productInfo.getProductId()); //productInfoVO.setProductName(productInfo.getProductName()); //productInfoVO.setProductPrice(productInfo.getProductPrice()); //productInfoVO.setProductDescription(productInfo.getProductDescription()); //productInfoVO.setProductIcon(productInfo.getProductIcon()); BeanUtils.copyProperties(productInfo,productInfoVO); productInfoVOList.add(productInfoVO); } } productVO.setProductInfoVOList(productInfoVOList); productVOList.add(productVO); } ResultVO resultVO = ResultVOUtil.success(productVOList); return resultVO; }}
分层查问数据,并拼装起来传给json。这里为了不便不必每次都创立ResultVO对象(因为没什么区别,步骤一样),创立了ResultVOUtils工具类。
public class ResultVOUtil { public static ResultVO success(Object object){ ResultVO resultVO = new ResultVO(); resultVO.setCode(0); resultVO.setMsg("胜利"); resultVO.setData(object); 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; }}
别离创立了它的传递胜利办法、传递失败办法。
查问果然查到了,如下面那张图。
5、和前端连贯显示页面
这里就须要以前连贯的虚拟机了,虚拟机ip地址是192.168.1.9,连贯这个网址,能够连上,然而会立即跳转到失败页面,因为这时相当于没有登陆。
这里如果想登陆须要传递openid的值,所以轻易传递一个即可,先登陆一个不跳转的页面,192.168.1.9/#/order,在console控制台中写document.cookie=‘openid=abc123’,这样就传递了一个值用来证实曾经登陆。
这时再登陆192.168.1.9,发现显示了页面。
这时候拜访不到是因为拜访的是虚拟机的地址,在虚拟机中批改nginx为本人本机电脑的ip地址。
vim /usr/local/nginx/conf/nginx.conf
在配置文件中批改。
这样就能够拜访了。