热销商品排行


商品数据库创建
1 2 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
实体类
1 2 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
,在其中编写对应的抽象方法
1 2 3 4 5 6 7 8 9 10
|
public interface ProductMapper {
List<Product> findHotProductList(); }
|
SQL映射文件配置
在resource/mapper
文件夹下创建映射文件ProductMapper.xml
,编写对应SQL映射语句
1 2 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>
|
单元测试
1 2 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
,在其中申明对应的抽象方法
1 2 3 4 5 6 7
| public interface IProductService {
List<Product> findHotProducts(); }
|
抽象方法实现
1 2 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; } }
|
单元测试
1 2 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); } } }
|
控制层
异常处理
业务层无新增异常,所以控制层无新增异常处理逻辑
设计请求
1 2 3 4
| request url: /product request method: GET request params: null response data: new JsonResult<List<Product>>
|
处理请求
创建商品控制层类ProductController
,继承于控制层基类BaseController
1 2 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
页面一加载,就像后端发送请求,获取热销商品数据并展示在前端页面
1 2 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
接口中编写对应抽象方法
1 2 3 4 5 6
|
Product findById(Integer id);
|
SQL映射文件配置
1 2 3
| <select id="findById" resultMap="productPojoMap"> select * from t_product where id=#{id}; </select>
|
单元测试
1 2 3 4 5
| @Test public void findById(){ Product product = productMapper.findById(10000017); System.out.println(product); }
|
业务层
规划异常
查询时,数据库中可能不存在该商品信息,此时应触发ProductNotFoundException
1 2 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
中编写对应抽象方法
1 2 3 4 5 6
|
Product getById(Integer id);
|
抽象方法实现
1 2 3 4 5 6 7 8
| @Override public Product getById(Integer id) { Product product = productMapper.findById(id); if(product==null){ throw new ProductNotFoundException("商品不存在异常"); } return product; }
|
单元测试
1 2 3 4 5
| @Test public void getById(){ Product product = productService.getById(10000017); System.out.println(product); }
|
控制层
异常处理
业务层新增ProductNotFound
异常,需要在控制层基类BaseController
中添加对应的异常处理逻辑
1 2 3 4
| else if (e instanceof ProductNotFoundException) { result.setState(8000); result.setMessage("商品不存在"); }
|
设计请求
1 2 3 4
| request url: /address/{id} request method: GET request params: Integer id response data: new JsonResult<Product>
|
处理请求
1 2 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");
|
编写商品数据加载代码
1 2 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>
|