热销商品排行


商品数据库创建
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 
 | CREATE TABLE t_product (id int(20) NOT NULL COMMENT '商品id',
 category_id int(20) DEFAULT NULL COMMENT '分类id',
 item_type varchar(100) DEFAULT NULL COMMENT '商品系列',
 title varchar(100) DEFAULT NULL COMMENT '商品标题',
 sell_point varchar(150) DEFAULT NULL COMMENT '商品卖点',
 price bigint(20) DEFAULT NULL COMMENT '商品单价',
 num int(10) DEFAULT NULL COMMENT '库存数量',
 image varchar(500) DEFAULT NULL COMMENT '图片路径',
 status int(1) DEFAULT '1' COMMENT '商品状态  1:上架   2:下架   3:删除',
 priority int(10) DEFAULT NULL COMMENT '显示优先级',
 created_time datetime DEFAULT NULL COMMENT '创建时间',
 modified_time datetime DEFAULT NULL COMMENT '最后修改时间',
 created_user varchar(50) DEFAULT NULL COMMENT '创建人',
 modified_user varchar(50) DEFAULT NULL COMMENT '最后修改人',
 PRIMARY KEY (id)
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
 
 | 
商品实体类的创建
在com.bang.store.pojo包下新建Product实体类
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 
 | package com.bang.store.pojo;
 import lombok.AllArgsConstructor;
 import lombok.Data;
 import lombok.NoArgsConstructor;
 
 
 
 
 @Data
 @AllArgsConstructor
 @NoArgsConstructor
 public class Product extends BasePojo{
 Integer id;
 Integer category_id;
 String item_type;
 String title;
 String sell_point;
 Long price;
 Integer num;
 String image;
 Integer status;
 Integer priority;
 
 }
 
 | 
持久层
规划执行的SQL语句
热销商品展示,本质是查询语句,根据优先级对所有已上架的商品进行排序,选取优先级最高的四条记录在页面进行展示
| 1
 | select * from t_product where status=1 order by priority DESC limit 0,4;
 | 
接口和抽象方法
新建商品持久层接口ProductMapper,在其中编写对应的抽象方法
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 
 | 
 
 public interface ProductMapper {
 
 
 
 
 List<Product> findHotProductList();
 }
 
 | 
SQL映射文件配置
在resource/mapper文件夹下创建映射文件ProductMapper.xml,编写对应SQL映射语句
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 
 | <?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE mapper
 PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
 <mapper namespace="com.bang.store.mapper.ProductMapper">
 
 <resultMap id="productPojoMap" type="com.bang.store.pojo.Product">
 <id column="id" property="id"/>
 <result column="category_id" property="categoryId"/>
 <result column="item_type" property="itemType"/>
 <result column="sell_point" property="sellPoint"/>
 <result column="created_time" property="createdTime"/>
 <result column="modified_time" property="modifiedTime"/>
 <result column="created_user" property="createdUser"/>
 <result column="modified_user" property="modifiedUser"/>
 </resultMap>
 
 <select id="findHotProductList" resultMap="productPojoMap">
 select * from t_product where status=1 order by priority DESC limit 0,4;
 </select>
 
 </mapper>
 
 | 
单元测试
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 
 | package com.bang.store.mapper;
 import com.bang.store.pojo.Product;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.springframework.boot.test.context.SpringBootTest;
 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
 
 import javax.annotation.Resource;
 import java.util.List;
 
 @SpringBootTest
 @RunWith(SpringJUnit4ClassRunner.class)
 public class ProductMapperTest {
 
 @Resource
 ProductMapper productMapper;
 @Test
 public void findHotProductList(){
 List<Product> productList = productMapper.findHotProductList();
 for (Product product : productList) {
 System.out.println(product);
 }
 }
 }
 
 | 
业务层
规划异常
无明显异常
接口和抽象方法
新建商品业务层接口IProductService,在其中申明对应的抽象方法
| 12
 3
 4
 5
 6
 7
 
 | public interface IProductService {
 
 
 
 List<Product> findHotProducts();
 }
 
 | 
抽象方法实现
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 
 | package com.bang.store.service.impl;
 import com.bang.store.mapper.ProductMapper;
 import com.bang.store.pojo.Product;
 import com.bang.store.service.IProductService;
 import org.springframework.stereotype.Service;
 
 import javax.annotation.Resource;
 import java.util.List;
 
 @Service
 public class ProductServiceImpl implements IProductService {
 
 @Resource
 ProductMapper productMapper;
 @Override
 public List<Product> findHotProducts() {
 List<Product> hotProductList = productMapper.findHotProductList();
 
 
 
 return hotProductList;
 }
 }
 
 | 
单元测试
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 
 | package com.bang.store.service;
 
 import com.bang.store.pojo.Product;
 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.SpringJUnit4ClassRunner;
 
 import java.util.List;
 
 @SpringBootTest
 @RunWith(SpringJUnit4ClassRunner.class)
 public class ProductServiceTest {
 
 @Autowired
 IProductService productService;
 @Test
 public void hotProductList(){
 List<Product> hotProducts = productService.findHotProducts();
 for (Product hotProduct : hotProducts) {
 System.out.println(hotProduct);
 }
 }
 }
 
 | 
控制层
异常处理
业务层无新增异常,所以控制层无新增异常处理逻辑
设计请求
| 12
 3
 4
 
 | request url: /productrequest method: GET
 request params: null
 response data: new JsonResult<List<Product>>
 
 | 
处理请求
创建商品控制层类ProductController,继承于控制层基类BaseController
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 
 | package com.bang.store.controller;
 import com.bang.store.pojo.Product;
 import com.bang.store.service.IProductService;
 import com.bang.store.utils.JsonResult;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 
 import java.util.List;
 
 @RestController
 @RequestMapping("/product")
 public class ProductController extends BaseController{
 @Autowired
 IProductService productService;
 @RequestMapping({"/",""})
 public JsonResult<List<Product>> findHotProducts(){
 List<Product> hotProducts = productService.findHotProducts();
 return new JsonResult<>(OK,"热销商品数据获取成功",hotProducts);
 }
 }
 
 | 
前端页面
index.html页面一加载,就像后端发送请求,获取热销商品数据并展示在前端页面
| 12
 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
 
 | <script>$(document).ready(function (){
 showHotList();
 });
 
 function showHotList() {
 $.ajax({
 url: "/product/"
 ,type: "GET"
 ,success: function (data){
 if(data.state == 200){
 alert("热销商品数据获取成功");
 
 
 $("#hot-list").empty();
 let hotProducts = data.data;
 for(let i=0;i<hotProducts.length;i++){
 let htmlContent = "<div class=\"col-md-12\">\n" +
 "<div class=\"col-md-7 text-row-2\"><a href=\"product.html?id#{id}\">#{title}</a></div>\n" +
 "<div class=\"col-md-2\">¥#{price}</div>\n" +
 "<div class=\"col-md-3\"><img src=../#{image}/collect.png class=\"img-responsive\" /></div>\n" +
 "</div>"
 htmlContent = htmlContent.replace("#{title}",hotProducts[i].title);
 htmlContent = htmlContent.replace("#{price}",hotProducts[i].price);
 htmlContent = htmlContent.replace("#{image}","../"+hotProducts[i].image);
 $("#hot-list").append(htmlContent);
 }
 }else{
 alert("热销商品数据获取失败 "+data.message);
 }
 }
 ,error:function (xmh){
 alert("热销商品数据获取发生未知错误"+xmh.status);
 }
 });
 }
 </script>
 
 | 
热销商品详情展示
用户点击热销商品列表中的某个商品名,即跳转到对应的商品详情页
热销商品列表页和商品详情页之间的关联,通过<a href=\"product.html?id#{id}\">#{title}</a>进行关联
持久层
规划执行的SQL语句
根据用户点击商品id查询对应的商品信息
| 1
 | select * from t_product where id=?;
 | 
接口和抽象方法
在ProductMapper接口中编写对应抽象方法
| 12
 3
 4
 5
 6
 
 | 
 
 
 
 Product findById(Integer id);
 
 | 
SQL映射文件配置
| 12
 3
 
 | <select id="findById" resultMap="productPojoMap">select * from t_product where id=#{id};
 </select>
 
 | 
单元测试
| 12
 3
 4
 5
 
 | @Testpublic void findById(){
 Product product = productMapper.findById(10000017);
 System.out.println(product);
 }
 
 | 
业务层
规划异常
查询时,数据库中可能不存在该商品信息,此时应触发ProductNotFoundException
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 
 | package com.bang.store.service.ex;
 public class ProductNotFoundException extends ServiceException{
 public ProductNotFoundException() {
 super();
 }
 
 public ProductNotFoundException(String message) {
 super(message);
 }
 
 public ProductNotFoundException(String message, Throwable cause) {
 super(message, cause);
 }
 
 public ProductNotFoundException(Throwable cause) {
 super(cause);
 }
 
 protected ProductNotFoundException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
 super(message, cause, enableSuppression, writableStackTrace);
 }
 }
 
 | 
接口和抽象方法
在IProductAddress中编写对应抽象方法
| 12
 3
 4
 5
 6
 
 | 
 
 
 
 Product getById(Integer id);
 
 | 
抽象方法实现
| 12
 3
 4
 5
 6
 7
 8
 
 | @Overridepublic Product getById(Integer id) {
 Product product = productMapper.findById(id);
 if(product==null){
 throw new ProductNotFoundException("商品不存在异常");
 }
 return product;
 }
 
 | 
单元测试
| 12
 3
 4
 5
 
 | @Testpublic void getById(){
 Product product = productService.getById(10000017);
 System.out.println(product);
 }
 
 | 
控制层
异常处理
业务层新增ProductNotFound异常,需要在控制层基类BaseController中添加对应的异常处理逻辑
| 12
 3
 4
 
 | else if (e instanceof ProductNotFoundException) {result.setState(8000);
 result.setMessage("商品不存在");
 }
 
 | 
设计请求
| 12
 3
 4
 
 | request url: /address/{id}request method: GET
 request params: Integer id
 response data: new JsonResult<Product>
 
 | 
处理请求
| 12
 3
 4
 5
 
 | @RequestMapping("/{id}")public JsonResult<Product> getById(@PathVariable("id") Integer id){
 Product product = productService.getById(id);
 return new JsonResult<>(OK,"商品数据获取成功",product);
 }
 
 | 
前端页面
通过$.getUrlParam("id")获取传递的参数值(商品堵塞id)
需要引入相关的库文件
| 1
 | <script type="text/javascript" src="../js/jquery-getUrlParam.js"></script>
 | 
| 1
 | let id =$.getUrlParam("id");
 | 
编写商品数据加载代码
| 12
 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
 
 | <script>$(document).ready(function (){
 
 let id =$.getUrlParam("id");
 showProduct(id);
 });
 
 function showProduct(id) {
 $.ajax({
 url: "/product/"+id
 ,type: "GET"
 ,success: function (data){
 if(data.state == 200){
 alert("商品数据获取成功");
 
 $("#product-title").html(data.data.title);
 $("#product-sell-point").html(data.data.sellPoint);
 $("#product-price").html(data.data.price);
 
 for(let i=1;i<=5;i++){
 $("#product-image-"+i).attr("src",".."+data.data.image+i+".jpg")
 $("#product-image-"+i+"-big").attr("src",".."+data.data.image+i+"_big.png")
 }
 
 }else{
 alert("商品数据获取失败 "+data.message);
 }
 }
 ,error:function (xmh){
 alert("商品数据获取发生未知错误"+xmh.status);
 }
 });
 }
 </script>
 
 |