针对热点数据的处理

出现问题:

当热点数据被并发且大量的访问时,将有大量的请求发送到数据库,数据库的压力会随之增大,从而产生一系列的问题

解决办法:

我们可以将数据加载到Redis缓存中,从而请求可以直接在缓存获取数据,减轻数据库的压力

大体思路:

在这里插入图片描述

实现方式一:Spring Data Redis

前言:

Spring Data Redis 是 Spring 的一部分,提供了在 Spring 应用中通过简单的配置就可以访问 Redis 服务,对 Redis 底层开发包进行了高度封装。在 Spring 项目中,可以使用Spring Data Redis来简化 Redis 操作。
网址:Spring Data Redis官网
在这里插入图片描述
Spring Data Redis中提供了一个高度封装的类:RedisTemplate,针对 Jedis 客户端中大量api进行了归类封装,将同一类型操作封装为operation接口,具体分类如下:
*
V a l u e O p e r a t i o n s :简单 K − V 操作 S t r i n g 数据操作 \color{#FF0000}{ValueOperations:简单K-V操作String数据操作} ValueOperations:简单KV操作String数据操作
*
S e t O p e r a t i o n s : s e t 类型数据操作 \color{#FF0000}{SetOperations:set类型数据操作} SetOperationsset类型数据操作
*
Z S e t O p e r a t i o n s : z s e t 类型数据操作 \color{#FF0000}{ZSetOperations:zset类型数据操作} ZSetOperationszset类型数据操作
*
H a s h O p e r a t i o n s :针对 h a s h 类型的数据操作 \color{#FF0000}{HashOperations:针对hash类型的数据操作} HashOperations:针对hash类型的数据操作
*
L i s t O p e r a t i o n s :针对 l i s t 类型的数据操作 \color{#FF0000}{ListOperations:针对list类型的数据操作} ListOperations:针对list类型的数据操作

项目要求:Redis中菜品缓存数据KEY的设计:dish_分类id

一:导入依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

二:添加缓存的代码例子

/**
     * 根据分类id查询菜品
     *
     * @param categoryId  菜品分类id
     * @return
     */
    @GetMapping("/list")
    @ApiOperation("根据分类id查询菜品")
    public R<List<DishVO>> list(Long categoryId) {
        //构造redis的key
        String key="dish_"+categoryId;
        //从Redis中获得缓存数据
        List<DishVO> list= (List<DishVO>) redisTemplate.opsForValue().get(key);
        //若缓存中存在该数据则直接返回,若没有执行添加缓存的操作
        if (list != null) {
            return R.success(list);
        }
        //封装查询条件
        Dish dish = new Dish();
        dish.setCategoryId(categoryId);
        dish.setStatus(Dish.ON);
		//根据查询条件查询对应菜品信息
        list = dishService.listWithFlavor(dish);
        //将查到的菜品信息和对应的缓存kay存储到Redis中
        redisTemplate.opsForValue().set(key,list);
        //返回查到的菜品信息
        return R.success(list);
    }
}

三:删除缓存

前提:当数据被更改或删除时,Redis缓存的数据也要同步更新

封装清理缓存的方法:

/**
     * 抽取清除缓存的方法
     * @param pattern
     */
    private void clearCache(String pattern){
    //删除无法进行模糊删除,所以先查询保存到set集合,再删除
        Set keys = redisTemplate.keys(pattern);
        redisTemplate.delete(keys);
    }

进行删除操作:

clearCache("dish_*");

实现方式二:Spring Cache

前言

Spring Cache是一个框架,实现了基于注解的缓存功能,只需要简单地加一个注解,就能实现缓存功能。

Spring Cache提供了一层抽象,底层可以切换不同的缓存实现。
CacheManager(缓存管理器)是Spring提供的各种缓存技术抽象接口。

针对不同的缓存技术需要实现不同的CacheManager:
在这里插入图片描述

RedisChacheManager常用注解

在这里插入图片描述

一:导入依赖

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-cache</artifactId>
        </dependency>

二:在启动类上开启缓存注解功能

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.transaction.annotation.EnableTransactionManagement;

@SpringBootApplication
@EnableTransactionManagement //开启注解方式的事务管理
@Slf4j
@EnableCaching//开启注解式缓存功能
public class ReggieApplication {
    public static void main(String[] args) {
        SpringApplication.run(ReggieApplication.class, args);
        log.info("server started");
    }
}

三:查询方法使用

/**
     * 条件查询
     *
     * @param categoryId
     * @return
     */
    @GetMapping("/list")
    @ApiOperation("根据分类id查询套餐")
    //redis的key 由cacheNames+key组成
    @Cacheable(cacheNames = "SetmealCache",key = "#categoryId")
    public R<List<Setmeal>> list(Long categoryId) {
        Setmeal setmeal = new Setmeal();
        setmeal.setCategoryId(categoryId);
        setmeal.setStatus(StatusConstant.ENABLE);

        List<Setmeal> list = setmealService.list(setmeal);
        return R.success(list);
    }

四:删除缓存

/**
     * 新增套餐
     * @param setmealDTO
     * @return
     */
    @PostMapping
    @ApiOperation("新增套餐")
    //删除所有SetmealCaChe
    @CacheEvict(cacheNames = "SetmealCache",key = "#setmealDTO.categoryId")
    public R save(@RequestBody SetmealDTO setmealDTO) {
        setmealService.saveWithDish(setmealDTO);
        return R.success();
    }

添加缓存拓展

@PostMapping
@Cacheable(cacheNames = "SetmealCache",key = "#user.id")
//#result用于引用方法调用的结果。对与支持的包装器,例如Optional,@result指的是实际对象,而不是包装器
//@Cacheable(cacheNames = "SetmealCache",key = "#result.id")
//方法参数可以通过索引访问。例如,可以通过#root.args[1]、#p1或#a1访问第二个参数,如果该信息可用,也可以按名称访问参数
//@Cacheable(cacheNames = "SetmealCache",key = "#p0.id")
//@Cacheable(cacheNames = "SetmealCache",key = "#a0.id")
//方法名称(#root.methodName)和目标类(#root.targetClass)的快捷方式也可用
//@Cacheable(cacheNames = "SetmealCache",key = "#root.args[0].id")
public User save(@RequestBody User user){
	userMapper.insert(user);
	return user;
}

二种实现方法的区别

Spring Data Redis:虽然较注解来说复杂、麻烦但是对于一个方法中要进行多种数据缓存时,灵活性高
Spring Cache:简单快捷

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值