SpringBoot使用redis结合mysql数据库(黑名单)渲染商品详情界面

目录

一、界面效果

二、前端代码

 三、后端代码(redis+blacklist)

3.1 ProducatController

3.2 ProductService

3.3 ProductDao

 3.4 映射文件


一、界面效果

二、前端代码

商品详情前端代码

<template>
  <van-nav-bar
    title="商品详情"
    left-text="返回"
    right-text="分享"
    left-arrow
    @click-left="onClickLeft"
    @click-right="onClickRight"
  />
  <van-swipe :autoplay="3000" lazy-render>
    <van-swipe-item v-for="image in product.img" :key="image">
      <img :src="image" style="width: 100%; height: 250px" @click="show" />
    </van-swipe-item>
  </van-swipe>
  <div class="Detail">
    <div class="price">
      <div>
        到手价¥<span>{{ product.price }}</span>
      </div>
    </div>
    <h4>{{ product.name }}</h4>
    <van-text-ellipsis
      rows="1"
      :content="product.subName"
      expand-text="展开"
      collapse-text="收起"
    />
  </div>
  <div class="warp">
    <van-tabs v-model:active="active" swipeable>
      <van-tab title="商品介绍">
        <div v-html="product.brief"></div>
      </van-tab>
      <van-tab title="规格参数"> 3333 </van-tab>
      <van-tab title="售后保障">
        <div>
          <div class="mod_tit_line">
            <h3>权利声明</h3>
          </div>
          京东商城上的所有商品信息、客户评价、商品咨询、网友讨论等内容,是京东商城重要的经营资源,未经许可,禁止非法转载使用。
          <div class="for_separator"></div>
          <p>
            <b>注:</b
            >本站商品信息均来自于厂商,其真实性、准确性和合法性由信息拥有者(厂商)负责。本站不提供任何保证,并不承担任何法律责任。
          </p>
        </div>
      </van-tab>
    </van-tabs>
  </div>
  <van-action-bar>
    <van-action-bar-icon icon="chat-o" text="客服" color="#ee0a24" />
    <van-action-bar-icon icon="cart-o" text="购物车" />
    <van-action-bar-icon icon="star" text="已收藏" color="#ff5000" />
    <van-action-bar-button type="warning" text="加入购物车" />
    <van-action-bar-button type="danger" text="立即购买" />
  </van-action-bar>
  <van-share-sheet
    v-model:show="showShare"
    title="立即分享给好友"
    :options="options"
    @select="onSelect"
  />
</template>
<script setup lang="ts">
import { ref, onMounted } from "vue";
import { showToast } from "vant";
import { useRoute, useRouter } from "vue-router";
import { productApi } from "@/api/index";
import { showImagePreview } from "vant";

const onClickLeft = () => history.back();
const onClickRight = () => {
  showShare.value = true;
};
const active = ref(0);
const route = useRoute();

onMounted(() => {
  callDetail();
});
const showShare = ref(false);
const options = [
  { name: "微信", icon: "wechat" },
  { name: "微博", icon: "weibo" },
  { name: "复制链接", icon: "link" },
  { name: "分享海报", icon: "poster" },
  { name: "二维码", icon: "qrcode" },
];

const onSelect = (option) => {
  showToast(option.name);
  showShare.value = false;
};
const show = () => {
  showImagePreview({
    images: product.value.img.split(","),
  });
};
const callDetail = () => {
  productApi.selectById.call({ id: route.query.id }).then((res: any) => {
    console.log(res);
    product.value = res;
    product.value.img=res.img.split(',')
  });
};
const product: any = ref({

});
</script>
<style>
.warp img {
  width: 100%;
}
</style>
<style scoped>
.van-action-bar {
  z-index: 50;
}
.price {
  color: red;
  font-size: 14px;
}
.price span {
  font-size: 20px;
}
.Detail {
  background-color: #fff;
  padding: 5px;
  border-radius: 0 0 10px 10px;
}
.Detail h4 {
  margin: 5px 0;
}
.Detail p {
  font-size: 15px;
}
.warp {
  margin-top: 10px;
  background-color: #fff;
  padding: 5px;
  border-radius: 10px 10px 0 0;
}
</style>

 三、后端代码(redis+blacklist)

3.1 ProducatController

    /**
     * 商品详情
     * @param id
     * @return
     */
    @GetMapping("/detail")
    public Product detail(Integer id) {
        int a=10;
        return productService.detail(id);
    }

3.2 ProductService

package com.beimao.service;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import cn.smart.core.exception.BizException;
import com.beimao.common.model.Product;
import com.beimao.dao.ProductDao;
import com.beimao.dao.ProductMapper;
import com.beimao.model.EsProduct;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class ProductService {
    /**
     * redis黑名单解决击穿问题
     */
    
    @Autowired
    private ProductDao productDao;
    @Resource(name = "redisTemplate")
    private HashOperations<String,String,String> hashOperations;
    @Resource(name = "redisTemplate")
    private ValueOperations<String, Product> valueOperations;

    // 黑名单key
    public static final String BLACKLIST_KEY = "product.hei";
    // 商品详情key
    public static final String ProductDetail_KEY = "product.detail";

  
    /**
     * 根据商品id 给商品详情
     * 先从redis中查询,如果redis中没有,则从数据库中查询
     *
     * @param id
     * @return
     */
    public Product detail(Integer id) {
        /**
         * 先验证商品id是否合法
         */
        if (id <= 0) {
            log.debug("商品id=》{}不合法", id);
            throw new BizException(100, "商品id不合法");

        }
        /**
         * 从redis里先检查 黑名单里是否有该商品
         * 如果有,抛出异常
         */
        Boolean b = hashOperations.hasKey(BLACKLIST_KEY, id.toString());
        if (b) {
            log.debug("商品不存在,商品在黑名单里,商品id=>{}", id);
            throw new BizException(101, "商品不存在");
        }
        /**
         * 黑名单没有
         * 直接从redis里查询是否有该商品
         * 有就返回,没有就查数据库
         */
        Product product = valueOperations.get(ProductDetail_KEY+id);
        if (ObjectUtil.isNotEmpty(product)) {
            log.debug("商品id=>{},从redis里查询到商品", id);
            return product;
        }
        /**
         * redis里面没有 就从数据库里面查
         * 数据库有就加入redis里面,没有就加入黑名单
         */
        product = productDao.detail(id);
        if (ObjectUtil.isEmpty(product)) {
            // 数据库查不到就加入黑名单
            hashOperations.put(BLACKLIST_KEY, id.toString(), DateUtil.now());
            log.debug("数据库里没有该商品,商品id=>{}加入黑名单", id);
        }
        // 数据库里面有就将该商品存到redis里面,设置ttl 一天
        /**
         *  错峰解决redis里的雪崩问题
         */
        int expire= RandomUtil.randomInt(-60 , 60);
        valueOperations.set(ProductDetail_KEY+id, product,24*60+expire, TimeUnit.MINUTES);
        return product;
    }

}

3.3 ProductDao

 /**
     * 根据商品id查询商品详情
     * @param id
     * @return
     */
    Product detail(Integer id);

 3.4 映射文件

<!--   根据id查询商品详情-->
    <select id="detail" resultType="com.beimao.common.model.Product">
        select id,subName,status,price,seq,tags,`name`,categoryId,img,brief
        from 205_product where id = #{id}
    </select>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/655642.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Redis 事件机制 - AE 抽象层

Redis 服务器是一个事件驱动程序&#xff0c;它主要处理如下两种事件&#xff1a; 文件事件&#xff1a;利用 I/O 复用机制&#xff0c;监听 Socket 等文件描述符上发生的事件。这类事件主要由客户端&#xff08;或其他Redis 服务器&#xff09;发送网络请求触发。时间事件&am…

IDEA提示Untrusted Server‘s certificate

如果你用的是Intellij系列IDE&#xff08;GoLand, PHPStorm, WebStorm, IDEA&#xff09;&#xff0c;突然弹出个提示『Untrusted Servers certificate 』 莫慌&#xff0c;这是因为你用了破解版的 IDE&#xff0c;破解过程中有个hosts绑定的操作&#xff1a; 0.0.0.0 account.…

Langchain-Chatchat之pdf转markdown格式

文章目录 背景开发环境loader文本解析步骤markdown格式的文本为什么选择markdown格式测试markdown格式提取表格原pdf表格markdown格式的表格 测试markdown格式的知识库运行项目修改文件加载器loader 其他问题运行项目报错查看系统当前的max_user_watches修改sysctl.conf配置 图…

【数据结构】直接选择排序详解!

文章目录 1.直接选择排序 1.直接选择排序 &#x1f427; begin 有可能就是 maxi &#xff0c;所以交换的时候&#xff0c;要及时更新 maxi &#x1f34e; 直接选择排序是不稳定的&#xff0c;例如&#xff1a; 9 [9] 5 [5]&#xff0c;排序后&#xff0c;因为直接选择排序是会…

【Python编程实战】基于Python语言实现学生信息管理系统

&#x1f3a9; 欢迎来到技术探索的奇幻世界&#x1f468;‍&#x1f4bb; &#x1f4dc; 个人主页&#xff1a;一伦明悦-CSDN博客 ✍&#x1f3fb; 作者简介&#xff1a; C软件开发、Python机器学习爱好者 &#x1f5e3;️ 互动与支持&#xff1a;&#x1f4ac;评论 &…

世界改变了我?还是我在改变着这个世界?-教育的魅力

目录 一、背景二、过程1.拥抱不确定性的心态2.应对变数的积极3.螺旋向上的能力4.突破自我的意志 三、总结 一、背景 现在这个时代唯一确定的就是不确定&#xff0c;社会发展太快了&#xff0c;尤其是中国的发展速度&#xff1b;大国生态人口生态。 有时候隐约中我自己也觉得和…

Linux源码编译安装MySQL + Qt连接MySQL

一、准备工作 1. 编译环境&#xff1a; 银河麒麟V10 飞腾D2000 CPU 2. 下载MySQL源码 这里编译的是5.7.44版本&#xff0c;带Boost库&#xff0c;这是官网的下载地址&#xff1a;MySQL :: Download MySQL Community Server (Archived Versions) 3. 解压压缩包 tar -zxvf mys…

springcloud-服务拆分与远程调用

一 微服务 1.1简单了解 SpringCloud SpringCloud是目前国内使用最广泛的微服务框架。官网地址&#xff1a;Spring Cloud。 SpringCloud集成了各种微服务功能组件&#xff0c;并基于SpringBoot实现了这些组件的自动装配&#xff0c;从而提供了良好的开箱即用体验&#xff1a…

ChatGPT自然科学应用,R语言lavaan结构方程模型、copula函数

R语言lavaan结构方程模型&#xff08;SEM&#xff09; 结构方程模型&#xff08;Sructural Equation Modeling&#xff0c;SEM&#xff09;是分析系统内变量间的相互关系的利器&#xff0c;可通过图形化方式清晰展示系统中多变量因果关系网&#xff0c;具有强大的数据分析功能和…

大模型部署_书生浦语大模型 _作业2

本节课可以让同学们实践 4 个主要内容&#xff0c;分别是&#xff1a; 1、部署 InternLM2-Chat-1.8B 模型进行智能对话 1.1安装依赖库&#xff1a; pip install huggingface-hub0.17.3 pip install transformers4.34 pip install psutil5.9.8 pip install accelerate0.24.1…

微软为团队推出了 Copilot

微软希望使其生成式人工智能品牌对团队更有用&#xff0c;特别是跨公司和大型企业组织的团队。 在年度 Build 开发者大会上&#xff0c;微软宣布推出 Team Copilot&#xff0c;这是其 Copilot 系列生成式 AI 技术的最新扩展。 与微软之前的 Copilot 品牌产品不同&#xff0c;…

炸裂!AI五分钟模仿爆款IP故事,涨粉速度太绝了!

‍ ‍大家好&#xff0c;我是向阳。 今天我要分享一个利用AI技术模仿爆款账号的小技巧&#xff0c;帮助大家迅速增加粉丝。这个方法简单实用&#xff0c;尤其适用于副业和本地生活领域。接下来&#xff0c;我将为大家详细讲解操作步骤。让我们开始吧。 副业赚钱&#xff1a;模…

本地开发正常 线上CI/CD构建项目过程报错文件未能正确引用

问题快照 原因分析&#xff1a; 一般遇到这样的错误就是 文件路径或者文件名称未能正确匹配 或者文件不存在 会报这样的错误 以为很好解决 但这次 都排查 了 就是 没发现原因 不管怎么说还是要感谢 GPT的能力(分析问题的能力) 先上图 当我看到 第四步的时候 我立马 去仓库里查…

Go Redis 实现邮件群发

一、安装 go get github.com/go-redis/redis/v8二、邮箱服务配置,以QQ邮箱为例 三、示例代码 package mainimport ("context""fmt"redis "github.com/go-redis/redis/v8""gopkg.in/gomail.v2""gopkg.in/ini.v1"&quo…

怎样查看JavaScript中没有输出结果的数组值?

在JavaScript中&#xff0c;可以方便地定义和使用数组&#xff0c;对于已经定义的数组&#xff0c;怎样查看其值呢&#xff1f; 看下面的示例&#xff0c;并运行它。 上面的示例中&#xff0c;标签不完整&#xff0c;请补充完整再试运行。你知道少了什么标签么&#xff1f; 注…

SEC批准以太坊ETF了吗?

原创 | 刘教链 隔夜BTC击穿了5日均线&#xff0c;回落至67k一线。凌晨传来美SEC批准以太坊ETF的消息&#xff0c;但是ETH上下插针&#xff0c;杵在3.8k&#xff0c;微微下跌。定睛仔细一看&#xff0c;SEC批准了&#xff0c;但又没完全批准&#xff0c;这特么是薛定谔的批准哈&…

本地部署 MiniCPM-Llama3-V 2.5

本地部署 MiniCPM-Llama3-V 2.5 0. 引言1. 性能评估2. 典型示例3. 本地部署4. 运行 WebUI Demo5. vLLM 部署 0. 引言 MiniCPM-Llama3-V 2.5 是 MiniCPM-V 系列的最新版本模型&#xff0c;基于 SigLip-400M 和 Llama3-8B-Instruct 构建&#xff0c;共 8B 参数量&#xff0c;相较…

AWS迁移与传输之AMS/MGN

AWS Application Migration Service&#xff08;AWS Application Migration Service简称为AWS MGN&#xff0c;MGN是migration的缩写。&#xff09;是一项全面的迁移服务&#xff0c;旨在帮助企业将其本地服务器和虚拟机迁移到云端&#xff0c;包括AWS和VMware Cloud on AWS。 …

【pyspark速成专家】11_Spark性能调优方法2

目录 ​编辑 二&#xff0c;Spark任务UI监控 三&#xff0c;Spark调优案例 二&#xff0c;Spark任务UI监控 Spark任务启动后&#xff0c;可以在浏览器中输入 http://localhost:4040/ 进入到spark web UI 监控界面。 该界面中可以从多个维度以直观的方式非常细粒度地查看Spa…

防止浏览器缓存了静态的配置等文件(例如外部的config.js 等文件)

防止浏览器缓存了静态的配置文件 前言1、在script引入的时候添加随机数1.1、引入js文件1.2、引入css文件2、通过html文件的<meta>设置防止缓存3、使用HTTP响应头:前言 在实际开发中浏览器的缓存问题一直是一个很让人头疼的问题,尤其是我们打包时候防止的静态配置文件c…