Redis缓存以及springCache的使用

目录

一、前言

1.1 问题引入

1.2 解决方法

二、Redis缓存

2.1 缓存的概念

2.2 实现思路

2.2.1 流程图

2.2.2 具体实战

2.2.3 清除缓存数据

三、使用 SpringCache 的注解

3.1 Spring Cache

3.1.1 介绍

3.1.2 引入maven坐标

3.1.3 常用注解

3.1.4 常用注解参数

3.2 入门Demo


一、前言

1.1 问题引入

        在同一个时间段内,向数据库进行大量操作(例如:添加大量的内容),就会频繁的查询数据库,导致数据库访问压力过大,最终导致系统响应慢、体验差

1.2 解决方法

使用redis缓存

二、Redis缓存

2.1 缓存的概念

缓存是数据交换的缓冲区(Cache),是数据存储(使用频繁的数据)的临时地方,相对来说他的读写性能比较高。当用户查询数据,首先在缓存中寻找,如果找到了则直接执行;如果找不到则去数据库中查找

优点:

  • 加快了响应速度
  • 减少了对数据库的读操作,数据库的压力降低

缺点:

  • 内存容量相对硬盘小

  • 缓存中的数据可能与数据库中数据不一致

  • 内存断电就会清空数据,造成数据丢失

2.2 实现思路

2.2.1 流程图

Redis缓存以及springCache的使用_第1张图片

2.2.2 具体实战

Redis缓存以及springCache的使用_第2张图片

如何使用redis可以浏览博主的另一篇文章:在java中操作redis数据库-CSDN博客

实战代码:

@RestController("userDishController")
@RequestMapping("/user/dish")
@Slf4j
@Api(tags = "C端-菜品浏览接口")
public class DishController {
    @Autowired
    private DishService dishService;

    @Autowired
    private RedisTemplate redisTemplate;
    /*根据分类id查询菜品*/
    @GetMapping("/list")
    @ApiOperation("根据分类id查询菜品")
    public Result> list(Long categoryId) {

        //构造redis中的key,规则:dish_分类id
        String key = "dish_" + categoryId;

        //查询redis中是否存在菜品数据(放进去的是什么类型的,取出来就是什么类型)
        List list = (List) redisTemplate.opsForValue().get(key);
        if(list != null && list.size() > 0){
            //如果存在,直接返回,无需查询数据库
            return Result.success(list);
        }
       
        Dish dish = new Dish();
        dish.setCategoryId(categoryId);
        dish.setStatus(StatusConstant.ENABLE);//查询起售中的菜品
        
        //如果不存在,查询数据库,将查询到的数据放入redis中
        list = dishService.listWithFlavor(dish);
        redisTemplate.opsForValue().set(key,list);
        return Result.success(list);
    }
}

2.2.3 清除缓存数据

为了保证数据库Redis中的数据保持一致,当数据库中发生变更时,缓存中需要清除,例如修改、删除、新增、启售、禁售操作

实战代码:

 @PostMapping
    @ApiOperation("新增菜品")
    public Result save(@RequestBody DishDTO dishDTO){
        log.info("新增菜品:{}",dishDTO);
        dishService.saveWithFlavor(dishDTO);

        //清除缓存数据
        String key = "dish_"+dishDTO.getCategoryId();
        redisTemplate.delete(key);
        return Result.success();
    }
  @DeleteMapping
    @ApiOperation("菜品的批量删除")
    public Result delete(@RequestParam List ids){
        log.info("菜品的批量删除:{}",ids);
        dishService.deleteBatch(ids);

        //清除缓存数据,把所有缓存删除,所有以dish_开头的key
        Set keys = redisTemplate.keys("dish_*");
        redisTemplate.delete(keys);
        return Result.success();
    }

三、使用 SpringCache 的注解

3.1 Spring Cache

3.1.1 介绍

Spring Cache 是一个框架,实现了基于注解的缓存功能,只需要简单地加一个注解,就能实现缓存功能。使用它可以简化我们缓存操作的代码。

Spring Cache 提供了一层抽象,底层可以切换不同的缓存实现,例如:

EHCache

Caffeine

Redis(常用)

3.1.2 引入maven坐标

        
            org.springframework.boot
            spring-boot-starter-cache
        

3.1.3 常用注解

Redis缓存以及springCache的使用_第3张图片

3.1.4 常用注解参数

value: 缓存管理器中配置的缓存的名称,这里可以理解为一个组的概念,缓存管理器中可以有多套缓存配置,每套都有一个名称,类似于组名,这个可以配置这个值,选择使用哪个缓存的名称,配置后就会应用那个缓存名称对应的配置。
key: 缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合。

在spring boot项目中,使用缓存技术只需在项目中导入相关缓存技术的依赖包,并在启动类上使用@EnableCaching开启缓存支持即可。

例如,使用Redis作为缓存技术,只需要导入Spring data Redis的maven坐标即可。

3.2 入门Demo

3.2.1 首先在启动类上加@EnableCaching注解

@Slf4j
@SpringBootApplication
@EnableCaching //开启缓存注解功能
public class CacheDemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(CacheDemoApplication.class,args);
        log.info("项目启动成功...");
    }
}

3.2.2 使用@CachePut注解

当前UserController的save方法是用来保存用户信息的,我们希望在该用户信息保存到数据库的同时,也往缓存中缓存一份数据,我们可以在save方法上加上注解 @CachePut,缓存的 value 为方法返回值。

作用: 将方法返回值,放入缓存

代码如下:

(主键返回)Mapper层中:

    @Insert("insert into user(name,age) values (#{name},#{age})")
    @Options(useGeneratedKeys = true,keyProperty = "id")
    void insert(User user);

Controller层中:

    @PostMapping
    @CachePut(cacheNames = "userCache",key = "#user.id") //如果使用springCache缓存数据,key的生成是: userCache::(拼上key的值)
//    @CachePut(value = "userCache",key = "#result.id") //对象导航
//    @CachePut(value = "userCache",key = "#p0.id")
//    @CachePut(value = "userCache",key = "#a0.id")
//    @CachePut(value = "userCache",key = "#root.args[0].id")
    public User save(@RequestBody User user){
        userMapper.insert(user);
        return user;
    }

说明:key的写法如下

#user.id : #user指的是方法形参的名称, id指的是user的id属性 , 也就是使用user的id属性作为key ;

#result.id : #result代表方法返回值,该表达式 代表以返回对象的id属性作为key ;

#p0.id:#p0指的是方法中的第一个参数,id指的是第一个参数的id属性,也就是使用第一个参数的id属性作为key ;

#a0.id:#a0指的是方法中的第一个参数,id指的是第一个参数的id属性,也就是使用第一个参数的id属性作为key ;

#root.args[0].id:#root.args[0]指的是方法中的第一个参数,id指的是第一个参数的id属性,也就是使用第一个参数的id属性作为key ;

3.2.3 使用@Cacheable注解

    @GetMapping
    @Cacheable(cacheNames = "userCache",key = "#id")
    public User getById(Long id){
        User user = userMapper.getById(id);
        return user;
    }

作用:在方法执行前,spring先查看缓存中是否有数据,如果有数据,则直接返回缓存数据;若没有数据,调用方法并将方法返回值放到缓存中,缓存的 value 为方法返回值。

3.2.4 使用@CacheEvict注解

  @DeleteMapping
    @CacheEvict(cacheNames = "userCache",key = "#id") //删除后要清理缓存
    public void deleteById(Long id){
        userMapper.deleteById(id);
    }

	@DeleteMapping("/delAll")
    @CacheEvict(cacheNames = "userCache",allEntries = true/*清除所有的缓存*/)
    public void deleteAll(){
        userMapper.deleteAll();
    }

作用:清理指定缓存 可以通过allEntries属性清理所有缓存

你可能感兴趣的:(spring,java,后端)