黑马点评Redis项目 P37练习题解答

449 阅读1分钟

题目要求

image.png

思路解析

由于ShopType信息在数据库中相对而言不会需要太多的修改,比较固定,所以可以直接在Redis建立缓存进行存取。

  1. 首先访问Redis查询是否有数据,有则使用Redis数据进行直接返回
  2. 如果没有,则直接到数据库查询进行返回。

Controller结构

如果没查到则显示首页列表数据异常。

@GetMapping("list")
public Result queryTypeList() {
    List<ShopType> shopTypes = shopTypeService.queryTypeList();
    if (shopTypes == null || shopTypes.size() == 0) {
        return Result.fail("首页列表数据异常");
    }
    return Result.ok(shopTypes);
}

Service层结构

public List<ShopType> queryTypeList() {
        //查询Redis是否有List数据,有则全部查出来
        List<String> redisShopTypeList = redisTemplate.opsForList().range(RedisConstants.CACHE_SHOP_TYPE, 0, -1);
        if (redisShopTypeList != null && redisShopTypeList.size() != 0) {

            List<ShopType> shopTypes = redisShopTypeList.stream()
                    .map(redisShopType -> JSONUtil.toBean(redisShopType, ShopType.class))
                    .collect(Collectors.toList());
//            for (String redisShopType : redisShopTypeList) {
//                ShopType shopType = JSONUtil.toBean(redisShopType, ShopType.class);
//                shopTypes.add(shopType);
//            }
            return shopTypes;
        }
        //如果没有,直接到数据库查询然后写回redis中
        List<ShopType> shopTypes = typeService.query().orderByAsc("sort").list();
        if (shopTypes == null || shopTypes.size() == 0) {
            return shopTypes;
        }
        for (ShopType shopType : shopTypes) {
            redisTemplate.opsForList().rightPush(RedisConstants.CACHE_SHOP_TYPE, JSONUtil.toJsonStr(shopType));
        }
        return shopTypes;
    }
  1. 方法直接访问Redis进行查找,使用redisTemplate进行opsForList查找再进行range方法的调用,ranger传入参数为0和-1,代表查找该key所对应的list里面的所有元素。

  2. 返回了一个List<String>之后,调用Steam方法将String元素封装成ShopTypeBean,形成一个新的List返回到前端。

  3. 假如没有,则直接进入MySQL中进行查找,返回前端的同时进行封装进Redis的操作。

  4. 至此,逻辑完成。

Mapper结构

mapper直接使用了Mybatis-Plus的封装方法,此处按下不表。

注意事项以及附加问题

直接使用RedisTemplate存入的话,会有十六进制码存入Redis的键值对中,所以要新建配置类进行处理,如下所示

@Configuration
public class RedisUtils {
    @Autowired
    private RedisTemplate redisTemplate;

    @PostConstruct
    public void init(){
        initRedisTemplate();
    }
    
    private void initRedisTemplate() {
        RedisSerializer stringSerializer = redisTemplate.getStringSerializer();
        redisTemplate.setKeySerializer(stringSerializer);
        redisTemplate.setHashKeySerializer(stringSerializer);
        redisTemplate.setValueSerializer(stringSerializer);
        redisTemplate.setHashValueSerializer(stringSerializer);
    }
}