点评项目-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

相关推荐
互联网搬砖老肖1 小时前
Web 架构之缓存策略实战:从本地缓存到分布式缓存
前端·缓存·架构
半桔13 小时前
【Linux手册】冯诺依曼体系结构
linux·缓存·职场和发展·系统架构
一个有女朋友的程序员14 小时前
Spring Boot 缓存注解详解:@Cacheable、@CachePut、@CacheEvict(超详细实战版)
spring boot·redis·缓存
yuren_xia15 小时前
在Spring Boot中集成Redis进行缓存
spring boot·redis·缓存
Lonely丶墨轩17 小时前
Redis 缓存策略:借助缓存优化数据库性能并保障数据一致性
数据库·redis·缓存
趁你还年轻_21 小时前
Redis大量key集中过期怎么办
数据库·redis·缓存
Wang's Blog1 天前
Monorepo架构: Nx Cloud 扩展能力与缓存加速
缓存·架构
·云扬·1 天前
【PmHub面试篇】PmHub 整合 TransmittableThreadLocal(TTL)缓存用户数据面试专题解析
缓存·面试·职场和发展
清风~徐~来1 天前
【Redis】类型补充
数据库·redis·缓存
一只帆記1 天前
SpringBoot EhCache 缓存
spring boot·后端·缓存