【Java秒杀方案】9.功能开发-【商品列表】 goodsList 页面缓存,thymeleaf 模板引擎 手动渲染

1 goodsList代码实现

1.1 前端

goodsList.html

在这里插入图片描述

http://localhost:8080/goods/toList 
点【详情】,跳转到商品详情页面
http://localhost:8080/goodsDetail.htm?goodsId=2
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>商品列表</title>
    <script type="text/javascript" src="/js/jquery.min.js" ></script>
    <script type="text/javascript" src="/js/common.js"></script>
</head>
<body>
<table>
    <tr>
        <td>序号</td>
        <td>商品编号</td>
        <td>商品名称</td>
        <td>商品价格</td>
        <td>商品库存</td>
        <td>商品图片</td>
        <td></td>
    </tr>
    <tr th:each="goods,stat : ${goodsList}">
        <td th:text="${stat.index}+1"></td>
        <td th:text="${goods.id}"></td>
        <td th:text="${goods.goodsName}"></td>
        <td th:text="${goods.seckillPrice}"></td>
        <td th:text="${goods.stockCount}"></td>
        <td>
            <img th:src="@{${goods.goodsImg}}"  width="120px" height="120px" />
        </td>
        <td>
            <!--
            <button type="button" th:attr="data-id=${goods.id}" οnclick="buy(this);">详情</button>
            <a th:href="'/goods/toDetail/'+${goods.id}">详情</a>
            -->
            <a th:href="'/goodsDetail.htm?goodsId='+${goods.id}">详情</a>
        </td>
    </tr>
</table>


<button id="exitBtn" type="button" onclick="exitLogin()">退出登录</button>
</body>
<script>
    console.log("goodsList");
    function buy(btn){
        var id=$(btn).data("id");
        alert(id);
        window.location.href="/goods/toDetail?id="+id;
    }

    function exitLogin(){
        $.ajax({
            url:"/login/exitLogin",
            type:"post",
            data:{

            },
            success:function (data){
                if(data.code==200){
                    alert("退出成功");
                    window.location.href="/login/toLogin"
                }else{
                    alert(data.message);
                }
            },
            error:function (data){
                alert("登录出现问题");
            }
        })
    }

</script>
</html>

1.2 后端

GoodsController 中关于商品列表的功能

package com.example.miaosha.controller;


import com.example.miaosha.mapper.GoodsMapper;
import com.example.miaosha.pojo.Goods;
import com.example.miaosha.pojo.Order;
import com.example.miaosha.pojo.User;
import com.example.miaosha.rabbitmq.MQSender;
import com.example.miaosha.service.IGoodsService;
import com.example.miaosha.vo.GoodsDetailVo;
import com.example.miaosha.vo.GoodsVo;
import com.example.miaosha.vo.RespBean;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.thymeleaf.context.WebContext;
import org.thymeleaf.spring5.view.ThymeleafViewResolver;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author cch
 * @since 2021-11-17
 */
@Controller
@RequestMapping("/goods")
public class GoodsController {
    @Autowired
    private IGoodsService goodsService;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private ThymeleafViewResolver thymeleafViewResolver;



    private String templateGoodsList="goodsList";
    private String templateGoods="goods:";
    private String templateGoodsDetail="goodsDetail:";

//商品列表展示tolist
// 商品详情

    @RequestMapping(value = "/toList",produces = "text/html;charset=utf-8")
    @ResponseBody
    public String tolist(Model model, User user, HttpServletRequest request, HttpServletResponse response){
        //if(null==user){ return "login"; }

        //Redis 中获取页面,如果不为空,直接返回html
        ValueOperations valueOperations = redisTemplate.opsForValue();
        String html = (String) valueOperations.get(templateGoodsList);
        if(!StringUtils.isEmpty(html)){
            return html;
        }


        model.addAttribute("user", user);

        List<GoodsVo> list=goodsService.findGoodsVo();
        model.addAttribute("goodsList", list);

        //如果为空,手动渲染,并且存入redis
        WebContext webContext = new WebContext(request, response, request.getServletContext(),request.getLocale(), model.asMap());

        html = thymeleafViewResolver.getTemplateEngine().process("goodsList",
                webContext);
        if(!StringUtils.isEmpty(html)){
            valueOperations.set(templateGoodsList,html,60, TimeUnit.SECONDS);
        }

        return html;
    }

    @RequestMapping(value = "/toList0")
    public String tolist0(Model model, User user){
        //if(null==user){ return "login"; }
        //如果为空,手动渲染,并且存入redis
        model.addAttribute("user", user);

        List<GoodsVo> list=goodsService.findGoodsVo();
        model.addAttribute("goodsList", list);

        return "goodsList";
    }

}

IGoodsService findGoodsVo

package com.example.miaosha.service;

import com.example.miaosha.pojo.Goods;
import com.baomidou.mybatisplus.extension.service.IService;
import com.example.miaosha.vo.GoodsVo;

import java.util.List;

/**
 * <p>
 *  服务类
 * </p>
 *
 * @author cch
 * @since 2021-11-17
 */
public interface IGoodsService extends IService<Goods> {

    List<Goods> getAll();

    List<GoodsVo> findGoodsVo();

    GoodsVo findGoodsVoById(Long goodsId);
}

GoodsServiceImpl

package com.example.miaosha.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.miaosha.pojo.Goods;
import com.example.miaosha.mapper.GoodsMapper;
import com.example.miaosha.service.IGoodsService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.miaosha.vo.GoodsVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author cch
 * @since 2021-11-17
 */
@Service
public class GoodsServiceImpl extends ServiceImpl<GoodsMapper, Goods> implements IGoodsService {
    @Autowired
    private GoodsMapper goodsMapper;
    @Override
    public List<Goods> getAll() {
        QueryWrapper<Goods> queryWrapper= new QueryWrapper<>();
        queryWrapper.apply("1=1");
        List<Goods> list = goodsMapper.selectList(queryWrapper);
        return list;
    }

    @Override
    public List<GoodsVo> findGoodsVo() {
        return goodsMapper.findGoodsVo();
    }

    @Override
    public GoodsVo findGoodsVoById(Long goodsId) {
        return goodsMapper.findGoodsVoById(goodsId);
    }
}

GoodsMapper

package com.example.miaosha.mapper;

import com.example.miaosha.pojo.Goods;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.miaosha.vo.GoodsVo;
import org.apache.ibatis.annotations.Mapper;

import java.util.List;

/**
 * <p>
 *  Mapper 接口
 * </p>
 *
 * @author cch
 * @since 2021-11-17
 */
@Mapper
public interface GoodsMapper extends BaseMapper<Goods> {

    List<GoodsVo> findGoodsVo();

    GoodsVo findGoodsVoById(Long goodsId);
}

GoodsMapper.xml

<select id="findGoodsVo" resultType="com.example.miaosha.vo.GoodsVo">
        select
            g.id,
            g.goods_name,
            g.goods_title,
            g.goods_detail,
            g.goods_img,
            g.goods_price,
            g.goods_stock,
            sg.seckill_price,
            sg.stock_count,
            sg.start_date,
            sg.end_date
        from
            t_goods g ,t_seckill_goods sg
        where g.id = sg.goods_id
    </select>
tolist0()直接通过thymeleaf模板引擎,把List<GoodsVo>放在model中,返回前台

tolist() 把商品页面先放在redis缓存中,
访问时,先去redis缓存中查找,有页面缓存的情况下,直接返回;
如果没有页面缓存,从数据库查找之后,手动渲染页面,把渲染之后的html存入redis

在这里插入图片描述

redis中,goodsList 过期时间为1分钟

GoodsVo

package com.example.miaosha.vo;

import com.example.miaosha.pojo.Goods;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.math.BigDecimal;
import java.util.Date;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class GoodsVo extends Goods {

    private BigDecimal seckillPrice;

    private Integer stockCount;

    private Date startDate;

    private Date endDate;
}

2.优化方面

2.1 页面缓存

把商品列表通过thymeleaf模板引擎,手动渲染,放在redis缓存,设置过期时间为1分钟
实际过程中,因为商品类别,还有商品列表分页,可以把热度最高的前几页放在缓存中

在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值