SpringBoot-Cache-Redis

SpringBoot缓存

spring定义了CacheCacheManager两个接口来统一管理不同的缓存技术,同时也支持使用JCache(JSR-107)注解来简化我们开发

  • Cache:缓存接口,定义缓存操作,实现有:RedisCache,EhCacheCache,ConcurrentMapCache等
  • CacheManager:缓存管理器,管理各种缓存(Cache)组件

几个常见的注解

缓存注解 解释
@Cacheable 主要配置在方法上,根据方法的请求参数对其结果进行缓存
@CacheEvict 清空缓存
@CachePut 方法被调用的同时,将结果缓存
@EnableCaching 开启基于注解的缓存

SpringBoot缓存的运行原理

缓存的自动配置类CacheAutoConfiguration导入了CacheConfigurationImportSelector
在这里插入图片描述
其为我们导入了十个缓存配置类
在这里插入图片描述
默认生效的是SimpleCacheConfiguration
在这里插入图片描述
其给容器中注册了一个CacheManager:ConcurrentMapCacheManager
获取和创建ConcurrentMapCacheManager类型的缓存组件,将数据保存在ConcurrentMap
在这里插入图片描述

运行流程:

1.方法运行之前,先去查询cache缓存组件,按照cacheName指定的名字获取,第一次获取缓存如果没有cache组件会自动创建出来

   public Cache getCache(String name) {
   	Cache cache = this.cacheMap.get(name);
   	if (cache == null && this.dynamic) {
   		synchronized (this.cacheMap) {
   			cache = this.cacheMap.get(name);
   			if (cache == null) {
   				cache = createConcurrentMapCache(name);
   				this.cacheMap.put(name, cache);
   			}
   		}
   	}
   	return cache;
   }

2.去cache中按照key查找缓存的内容,key默认就是方法的参数

   protected Object lookup(Object key) {
   	return this.store.get(key);
   }

3.没有查找到缓存就调用目标方法,也就是去查找数据库
4.将找到的结果放进缓存中

public void put(Object key, @Nullable Object value) {
		this.store.put(key, toStoreValue(value));
	}

@Cacheable注解总的来说就是其标注的方法执行之前先来检查缓存中有没有数据,没有就去数据库中查并将结果放进缓存

缓存实例

1.开启基于注解的缓存

@SpringBootApplication
@EnableCaching//开启基于注解的缓存
@MapperScan(value = "com.lb.springboot.mapper")
public class SpringbootCacheApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringbootCacheApplication.class, args);
    }

}

2.在方法上标注@Cacheable并设置缓存名

@Service
public class EmployeeService {

    @Autowired
    EmployeeMapper employeeMapper;

    @Cacheable(value = "getEmp")
    public Employee getEmp(int id){
        System.out.println("查询用户ID:"+id);
        return employeeMapper.getEmp(id);
    }
}

3.效果展示
@Cacheable
第一次获取员工信息时,因为没有缓存在没有该信息,所以会执行方法去数据库查找,并将结果放进缓存中
在这里插入图片描述
第二次获取时,因为缓存已经有该信息,所以就不需要执行方法去数据库查找而是直接从缓存中获取
在这里插入图片描述
@CachePut

在方法上标注@CachePut并设置缓存名

    @CachePut(value = "emp",key = "#result.id")
    public Employee updateEmp(Employee employee){
        System.out.println("更新用户ID:"+employee.getId());
        employeeMapper.updateEmp(employee);
        return employee;
    }

效果
每次调用方法都会执行
在这里插入图片描述
并且将更新后的数据保存在缓存中
在这里插入图片描述
CacheEvict

在方法上标注@CacheEvict并设置要删除的key

    @CacheEvict(value = "emp",key = "#id")
    public void deleteEmp(int id){
        System.out.println("deleteEmp: "+id);
    }

效果
会把缓存中对应的key删除
在这里插入图片描述
随后获取数据时,因为缓存中该数据被删除了,所以需要重新调用方法去数据库查询
在这里插入图片描述

springboot整合redis

导入redis依赖

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

启动redis服务和连接redis
在这里插入图片描述

在这里插入图片描述
springboot中redis操作主要有两大类

  • RedisTemplate<Object,Object>
  • StringRedisTemplate<String,String>

StringRedisTemplate继承RedisTemplate

redis支持String,Hash,Set,List,Zset五大类型,这里只测试List和String,其他类型的方法都是大同小异

public class SpringbootRedisApplicationTests {

    @Autowired
    RedisTemplate redisTemplate;

    @Autowired
    StringRedisTemplate stringRedisTemplate;

    @Test
    public void contextLoads() {
        stringRedisTemplate.opsForValue().set("msg","redis" );
        System.out.println(stringRedisTemplate.opsForValue().get("msg"));

在这里插入图片描述

public class SpringbootRedisApplicationTests {

    @Autowired
    RedisTemplate redisTemplate;

    @Autowired
    StringRedisTemplate stringRedisTemplate;

    @Test
    public void contextLoads() {
        List<String> list = new ArrayList<>();
        list.add("1");
        list.add("2");
        list.add("3");
        list.add("4");
        stringRedisTemplate.opsForList().leftPushAll("list",list );
        System.out.println(stringRedisTemplate.opsForList().index("list",2 ));
    }

在这里插入图片描述
在请求中使用redis

@RestController
public class cacheController {
    @Autowired
    EmployeeService employeeService;

    @GetMapping("/getEmp/{id}")
    public Employee get(@PathVariable("id") int id){
        Employee employee = employeeService.getEmp(id);
        return employee;
    }
}

注意把对象存进redis中时需要序列化
在这里插入图片描述
请求

@RestController
public class cacheController {
    @Autowired
    EmployeeService employeeService;

    @GetMapping("/getEmp/{id}")
    public Employee get(@PathVariable("id") int id){
        Employee employee = employeeService.getEmp(id);
        return employee;
    }
}

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

完整代码在我的GitHub

发布了65 篇原创文章 · 获赞 74 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/qq_40866897/article/details/90116760
今日推荐