点评项目-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内存消耗异常飙升?深入排查与Big Key/Hot Key的根治方案
jvm·数据库·spring boot·redis·spring·缓存
成为你的宁宁3 小时前
【Redis 从入门到实战:详细讲解 Redis 安装配置、RDB/AOF 数据持久化方案、一主两从同步部署,深入剖析哨兵模式工作原理与哨兵模式高可用全攻略】
数据库·redis·缓存
ifeng09183 小时前
HarmonyOS网络请求优化实战:智能缓存、批量处理与竞态处理
网络·缓存·harmonyos
5***o5003 小时前
前端构建工具缓存清理,解决依赖问题
前端·缓存
一叶飘零_sweeeet7 小时前
2025 年 Redis 面试天花板
redis·缓存·面试
d***9358 小时前
Redis五种用途
数据库·redis·缓存
stevenzqzq14 小时前
android recyclerview缓存2_四级缓存机制
android·spring boot·缓存
q***d17314 小时前
后端缓存技术学习资源,Redis+Memcached
redis·学习·缓存
麦兜*16 小时前
Redis在Web3中的应用探索:作为链下状态缓存与索引层
java·spring boot·redis·spring cloud·缓存·docker·web3
qwer12321ck761 天前
Maven在本地仓库缓存了失败的下载记录
缓存·maven