点评项目-5-商户查询缓存,从 2s 优化到 12ms

业务需求:当前端发送 shop/id 的请求时,我们需要向前端响应对应 id 的详细数据给前端

直接查询 mysql 效率比较低,我们可以使用 redis 作为中间件进行数据的缓存,先查询 redis ,若redis 中未查询到,则在 mysql 中查询,并在查询后写入 redis 中

第一步,Controller

java 复制代码
@RestController
@RequestMapping("/shop")
public class ShopController {
    
    @Resource
    public ShopService shopService;
    
    //接收携带店铺id的请求,响应店铺信息
    @GetMapping("/{id}")
    public Result queryShopById(@PathVariable("id") Long id){
        return shopService.getById(id);
    }
    
}

实现店铺信息的封装 Pojo 类

java 复制代码
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("tb_shop")
public class Shop implements Serializable {

    private static final long serialVersionUID = 1L;

    /**
     * 主键
     */
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;

    /**
     * 商铺名称
     */
    private String name;

    /**
     * 商铺类型的id
     */
    private Long typeId;

    /**
     * 商铺图片,多个图片以','隔开
     */
    private String images;

    /**
     * 商圈,例如陆家嘴
     */
    private String area;

    /**
     * 地址
     */
    private String address;

    /**
     * 经度
     */
    private Double x;

    /**
     * 维度
     */
    private Double y;

    /**
     * 均价,取整数
     */
    private Long avgPrice;

    /**
     * 销量
     */
    private Integer sold;

    /**
     * 评论数量
     */
    private Integer comments;

    /**
     * 评分,1~5分,乘10保存,避免小数
     */
    private Integer score;

    /**
     * 营业时间,例如 10:00-22:00
     */
    private String openHours;

    /**
     * 创建时间
     */
    private LocalDateTime createTime;

    /**
     * 更新时间
     */
    private LocalDateTime updateTime;


    @TableField(exist = false)
    private Double distance;
}

第二步,Service 及其实现类

java 复制代码
public interface ShopService {
    Result getById(Long id);
}
java 复制代码
@Service
public class ShopServiceImpl implements ShopService {
    @Resource
    private StringRedisTemplate stringRedisTemplate;
    @Resource
    private ShopMapper shopMapper;

    @Override
    public Result getById(Long id) {
        //先在 redis 中查询
        String shopJson = stringRedisTemplate.opsForValue().get("cache:shop:" + id);
        if(StrUtil.isNotBlank(shopJson)){
            return Result.ok(JSONUtil.toBean(shopJson,Shop.class));
        }
        //redis 中没有,在 mysql 中查询
        Shop shop = shopMapper.selectById(id);
        if(shop == null){
            //mysql 中也没有,返回未查询到
            return Result.fail("未查询到该店铺ToT");
        }
        //查到了,将查询到的数据写入 redis
        stringRedisTemplate.opsForValue().set("cache:shop:" + id,JSONUtil.toJsonStr(shop));
        return Result.ok(shop);
    }
}

最后一步,将店铺查询的拦截放开,进行测试

java 复制代码
    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //添加更新 token 拦截器,默认先添加先拦截,也可以通过.order() 来设置拦截的先后顺序
        registry.addInterceptor(new RefreshTokenInterceptor(stringRedisTemplate));
        //添加判断是否登录的拦截器
        registry.addInterceptor(new LoginInterceptor())
                .excludePathPatterns("/user/code", "/user/login","/shop/**");
    }

第一次访问时耗时两秒多,存入 redis 缓存后,第二次查询效率显著提升,从 2s 优化到了 12ms

相关推荐
清风徐来QCQ11 分钟前
Redis以及如何在springboot中使用
数据库·redis·缓存
彭于晏Yan1 小时前
高并发系统缓存更新策略:四种方案深度剖析与最优选择
spring boot·redis·缓存
不是株18 小时前
Redis(入门篇)
数据库·redis·缓存
qq_2816842120 小时前
Apt-Serve:基于混合缓存与自适应调度突破LLM推理KV缓存瓶颈,吞吐量提升8.8倍
缓存
1104.北光c°21 小时前
深入浅出 Elasticsearch:从搜索框到精准排序的架构实战
java·开发语言·elasticsearch·缓存·架构·全文检索·es
FakeOccupational21 小时前
【电路笔记 STM32】Cortex-M7 内核上的数据缓存结构图 + MPU内存保护单元 + Cache基本操作 + Cache&DMA 时序图
笔记·stm32·缓存
AMoon丶21 小时前
Golang--内存管理
开发语言·后端·算法·缓存·golang·os
小江的记录本1 天前
【Redis】Redis常用命令速查表(完整版)
java·前端·数据库·redis·后端·spring·缓存
ZHOUPUYU1 天前
从缓存到消息队列的全面应用,PHP与Redis深度实战
redis·缓存·php
我真会写代码2 天前
从入门到精通:Kafka核心原理与实战避坑指南
分布式·缓存·kafka