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

相关推荐
菜♕卷2 小时前
Redis-02 持久化
数据库·redis·缓存
狼与自由6 小时前
redis 为什么速度快
数据库·redis·缓存
binbinxyz8 小时前
Redis BigKey问题
数据库·redis·缓存
weixin_5318042410 小时前
消息队列(如RabbitMQ、Kafka)的使用与原理。缓存系统(如Redis、Memcached)的使用与优化。
缓存·kafka·rabbitmq
w_t_y_y10 小时前
Redis操作(三)RedisTemplate(2)StringRedisTemplate常见API
数据库·redis·缓存
醋椒豆腐12 小时前
、Redis 安装
数据库·redis·缓存
敲代码的小王!12 小时前
redis高级(面试题一)
数据库·redis·缓存
明志刘明12 小时前
昇思MindSpore进阶教程--单节点数据缓存(中)
人工智能·深度学习·缓存·mindspore·昇思
运维开发小白13 小时前
Redis入门第四步:Redis发布与订阅
数据库·redis·缓存