业务需求:当前端发送 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