Springboot's product design hot-selling ranking realization

Get into the habit of writing together! This is the 4th day of my participation in the "Nuggets Daily New Plan·April Update Challenge", click to view the details of the event .

Best-selling products

1 Commodity - Create Data Table

1. Use the use command to select the store database first.

USE store;
复制代码

2. Create the t_product data table in the store database.

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;
复制代码

2 Commodity - create entity class

Create the com.cy.store.entity.Product class and inherit from the BaseEntity class. Declare properties in the class that correspond to those in the data table.

package com.cy.store.entity;

/** 商品数据的实体类 */
public class Product extends BaseEntity implements Serializable {
    private Integer id;
    private Integer categoryId;
    private String itemType;
    private String title;
    private String sellPoint;
    private Long price;
    private Integer num;
    private String image;
    private Integer status;
    private Integer priority;

    // Generate: Getter and Setter、Generate hashCode() and equals()、toString()
}
复制代码

3 Commodities - Top Selling Ranking - Persistence Layer

3.1 Planning the SQL statements to be executed

The SQL statement to query the list of hot-selling items is roughly.

SELECT * FROM t_product WHERE status=1 ORDER BY priority DESC LIMIT 0,4
复制代码

3.2 Interfaces and abstract methods

Create the ProductMapper interface under the com.cy.store.mapper package and add the method findHotList() to query the hot-selling products in the interface.

package com.cy.store.mapper;
import com.cy.store.entity.Product;
import java.util.List;

/** 处理商品数据的持久层接口 */
public interface ProductMapper {
    /**
     * 查询热销商品的前四名
     * @return 热销商品前四名的集合
     */
    List<Product> findHotList();
}
复制代码

3.3 Configure SQL Mapping

1. Create the ProductMapper.xml file in the main\resources\mapper folder, and configure the mapping of the findHotList() method in the file.

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.cy.store.mapper.ProductMapper">
    <resultMap id="ProductEntityMap" type="com.cy.store.entity.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_user" property="createdUser"/>
        <result column="created_time" property="createdTime"/>
        <result column="modified_user" property="modifiedUser"/>
        <result column="modified_time" property="modifiedTime"/>
    </resultMap>

    <!-- 查询热销商品的前四名:List<Product> findHostList() -->
    <select id="findHotList" resultMap="ProductEntityMap">
        SELECT
            *
        FROM
            t_product
        WHERE
            status=1
        ORDER BY
            priority DESC
            LIMIT 0,4
    </select>
</mapper>
复制代码

2. Create the ProductMapperTests test class under the com.cy.store.mapper package and add the test method.

package com.cy.store.mapper;
import com.cy.store.entity.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.SpringRunner;
import java.util.List;

@RunWith(SpringRunner.class)
@SpringBootTest
public class ProductMapperTests {
    @Autowired
    private ProductMapper productMapper;

    @Test
    public void findHotList() {
        List<Product> list = productMapper.findHotList();
        System.out.println("count=" + list.size());
        for (Product item : list) {
            System.out.println(item);
        }
    }
}
复制代码

4 Commodities - Best Selling Ranking - Business Layer

4.1 Planning exceptions

Description : No exception.

4.2 Interfaces and Abstract Methods

Create the com.cy.store.service.IProductService interface and add the findHotList() method to the interface.

package com.cy.store.service;
import com.cy.store.entity.Product;
import java.util.List;

/** 处理商品数据的业务层接口 */
public interface IProductService {
    /**
     * 查询热销商品的前四名
     * @return 热销商品前四名的集合
     */
    List<Product> findHotList();
}
复制代码

4.3 Implementing abstract methods

1. Create the com.cy.store.service.impl.ProductServiceImpl class and add the @Service annotation; declare the persistence layer object in the class and implement the methods in the interface.

package com.cy.store.service.impl;
import com.cy.store.entity.Product;
import com.cy.store.mapper.ProductMapper;
import com.cy.store.service.IProductService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;

/** 处理商品数据的业务层实现类 */
@Service
public class ProductServiceImpl implements IProductService {
    @Autowired
    private ProductMapper productMapper;

    @Override
    public List<Product> findHotList() {
        List<Product> list = productMapper.findHotList();
        for (Product product : list) {
            product.setPriority(null);
            product.setCreatedUser(null);
            product.setCreatedTime(null);
            product.setModifiedUser(null);
            product.setModifiedTime(null);
        }
        return list;
    }
}
复制代码

2. Create a test class ProductServiceTests under the com.cy.store.service package, and write test methods.

package com.cy.store.service;
import com.cy.store.entity.Product;
import com.cy.store.service.ex.ServiceException;
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.SpringRunner;
import java.util.List;

@RunWith(SpringRunner.class)
@SpringBootTest
public class ProductServiceTests {
    @Autowired
    private IProductService productService;

    @Test
    public void findHotList() {
        try {
            List<Product> list = productService.findHotList();
            System.out.println("count=" + list.size());
            for (Product item : list) {
                System.out.println(item);
            }
        } catch (ServiceException e) {
            System.out.println(e.getClass().getSimpleName());
            System.out.println(e.getMessage());
        }
    }
}
复制代码

5 Commodities-Best Selling Ranking-Controller

5.1 Handling exceptions

Description : No exception.

5.2 Design Request

1. Design the request submitted by the user, and design the way to respond.

请求路径:/products/hot_list
请求参数:无
请求类型:GET
响应结果:JsonResult<List<Product>>
是否拦截:否,需要将index.html和products/**添加到白名单
复制代码

2.在LoginInterceptorConfigurer类中将index.html页面和products/**请求添加到白名单。

patterns.add("/web/index.html");
patterns.add("/products/**");
复制代码

5.3 处理请求

1.创建com.cy.controller.ProductController类继承自BaseController类,类添加@RestController和@RequestMapping("products")注解,并在类中添加业务层对象。

package com.cy.store.controller;
import com.cy.store.entity.Product;
import com.cy.store.service.IProductService;
import com.cy.store.util.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("products")
public class ProductController extends BaseController {
    @Autowired
    private IProductService productService;
}
复制代码

2.在类中添加处理请求的getHotList()方法。

@RequestMapping("hot_list")
public JsonResult<List<Product>> getHotList() {
    List<Product> data = productService.findHotList();
    return new JsonResult<List<Product>>(OK, data);
}
复制代码

3.完成后启动项目,直接访问http://localhost:8080/products/hot_list进行测试。

6 商品-热销排行-前端页面

1.在index.html页面给“热销排行”列表的div标签设置id属性值。

<div id="hot-list" class="panel-body panel-item">
	<!-- ... -->
</div>
复制代码

2.在index.html页面中body标签内部的最后,添加展示热销排行商品的代码。

<script type="text/javascript">
$(document).ready(function() {
    showHotList();
});

function showHotList() {
    $("#hot-list").empty();
    $.ajax({
        url: "/products/hot_list",
        type: "GET",
        dataType: "JSON",
        success: function(json) {
            let list = json.data;
            console.log("count=" + list.length);
            for (let i = 0; i < list.length; i++) {
                console.log(list[i].title);
                let html = '<div class="col-md-12">'
                  + '<div class="col-md-7 text-row-2"><a href="product.html?id=#{id}">#{title}</a></div>'
                  + '<div class="col-md-2">¥#{price}</div>'
                  + '<div class="col-md-3"><img src="..#{image}collect.png" class="img-responsive" /></div>'
                + '</div>';

                html = html.replace(/#{id}/g, list[i].id);
                html = html.replace(/#{title}/g, list[i].title);
                html = html.replace(/#{price}/g, list[i].price);
                html = html.replace(/#{image}/g, list[i].image);

                $("#hot-list").append(html);
            }
        }
    });
}
</script>
复制代码

3.完成后启动项目,直接访问http://localhost:8080/web/index.html进行测试。

显示商品详情

1 商品-显示商品详情-持久层

1.1 规划需要执行的SQL语句

根据商品id显示商品详情的SQL语句大致是。

SELECT * FROM t_product WHERE id=?
复制代码

1.2 接口与抽象方法

在ProductMapper接口中添加抽象方法。

/**
 * 根据商品id查询商品详情
 * @param id 商品id
 * @return 匹配的商品详情,如果没有匹配的数据则返回null
 */
Product findById(Integer id);
复制代码

1.3 配置SQL映射

1.在ProductMapper.xml文件中配置findById(Integer id)方法的映射。

<!-- 根据商品id查询商品详情:Product findById(Integer id) -->
<select id="findById" resultMap="ProductEntityMap">
    SELECT
    	*
    FROM
    	t_product
    WHERE
    	id=#{id}
</select>
复制代码

2.在ProductMapperTests测试类中添加测试方法。

@Test
public void findById() {
    Integer id = 10000017;
    Product result = productMapper.findById(id);
    System.out.println(result);
}
复制代码

2 商品-显示商品详情-业务层

2.1 规划异常

如果商品数据不存在,应该抛出ProductNotFoundException,需要创建com.cy.store.service.ex.ProductNotFoundException异常。

package com.cy.store.service.ex;

/** 商品数据不存在的异常 */
public class ProductNotFoundException extends ServiceException {
    // Override Methods...
}
复制代码

2.2 接口与抽象方法

在业务层IProductService接口中添加findById(Integer id)抽象方法。

/**
 * 根据商品id查询商品详情
 * @param id 商品id
 * @return 匹配的商品详情,如果没有匹配的数据则返回null
 */
Product findById(Integer id);
复制代码

2.3 实现抽象方法

1. In the ProductServiceImpl class, implement the findById(Integer id) abstract method in the interface.

@Override
public Product findById(Integer id) {
    // 根据参数id调用私有方法执行查询,获取商品数据
    Product product = productMapper.findById(id);
    // 判断查询结果是否为null
    if (product == null) {
        // 是:抛出ProductNotFoundException
        throw new ProductNotFoundException("尝试访问的商品数据不存在");
    }
    // 将查询结果中的部分属性设置为null
    product.setPriority(null);
    product.setCreatedUser(null);
    product.setCreatedTime(null);
    product.setModifiedUser(null);
    product.setModifiedTime(null);
    // 返回查询结果
    return product;
}
复制代码

2. Write test methods in the ProductServiceTests test class.

@Test
public void findById() {
    try {
        Integer id = 100000179;
        Product result = productService.findById(id);
        System.out.println(result);
    } catch (ServiceException e) {
        System.out.println(e.getClass().getSimpleName());
        System.out.println(e.getMessage());
    }
}
复制代码

3 Product - Display Product Details - Controller

3.1 Handling exceptions

Add an exception to handle ProductNotFoundException in the handleException() method in the BaseController class.

// ...
else if (e instanceof ProductNotFoundException) {
	result.setState(4006);
}
// ...
复制代码

3.2 Design Request

Design the requests submitted by users, and design the way they respond.

请求路径:/products/{id}/details
请求参数:@PathVariable("id") Integer id
请求类型:GET
响应结果:JsonResult<Product>
复制代码

3.3 Handling the request

1. Add the getById() method to handle the request in the ProductController class.

@GetMapping("{id}/details")
public JsonResult<Product> getById(@PathVariable("id") Integer id) {
    // 调用业务对象执行获取数据
    Product data = productService.findById(id);
    // 返回成功和数据
    return new JsonResult<Product>(OK, data);
}
复制代码

2. Start the project after completion and directly visit http://localhost:8080/products/10000017/details for testing.

4 Product - Display Product Details - Front-End Page

1. Check whether the jquery-getUrlParam.js file is imported at the end of the body tag of the product.html page. If it is imported, there is no need to repeat it.

<script type="text/javascript" src="../js/jquery-getUrlParam.js"></script>
复制代码

2. Add the code to get the current product details at the end of the body tag in the product.html page.

<script type="text/javascript">
let id = $.getUrlParam("id");
console.log("id=" + id);
$(document).ready(function() {
    $.ajax({
        url: "/products/" + id + "/details",
        type: "GET",
        dataType: "JSON",
        success: function(json) {
            if (json.state == 200) {
                console.log("title=" + json.data.title);
                $("#product-title").html(json.data.title);
                $("#product-sell-point").html(json.data.sellPoint);
                $("#product-price").html(json.data.price);

                for (let i = 1; i <= 5; i++) {
                    $("#product-image-" + i + "-big").attr("src", ".." + json.data.image + i + "_big.png");
                    $("#product-image-" + i).attr("src", ".." + json.data.image + i + ".jpg");
                }
            } else if (json.state == 4006) { // 商品数据不存在的异常
                location.href = "index.html";
            } else {
                alert("获取商品信息失败!" + json.message);
            }
        }
    });
});
</script>
复制代码

3. Start the project after completion, first visit http://localhost:8080/web/index.html

page, and then click on a sub-item in "Best Selling Ranking", it will jump to the product.html product details page, and observe whether the current product information is loaded on the page.

Guess you like

Origin juejin.im/post/7082961463052075021