小白入门-Redis学习第三篇

之前已经讲了redis的简单介绍和在程序中的简单使用,这篇我们讲一下使用Annotation缓存数据

之前我们讲了手动操作redis进行存取操作,在真实的业务场景中,我们并不想这样去使用,而是把Redis当做一种缓存来使用,把service或者dao层的数据进行缓存, 最简单的方式就是通过注解。在SpringBoot中使用Redis做缓存也非常简单,只需要在pom中引入spring-boot-starter-cache即可。

Spring缓存的常用注解

  • @CacheConfig:主要用于配置该类中会用到的一些共用的缓存配置。在这里@CacheConfig(cacheNames = “users”):配置了该数据访问对象中返回的内容将存储于名为users的缓存对象中,我们也可以不使用该注解,直接通过@Cacheable自己配置缓存集的名字来定义。

  • @Cacheable:配置了findByName函数的返回值将被加入缓存。同时在查询时,会先从缓存中获取,若不存在才再发起对数据库的访问。该注解主要有下面几个参数:

  1. value、cacheNames:两个等同的参数(cacheNames为Spring4新增,作为value的别名),用于指定缓存存储的集合名。由于Spring 4中新增了@CacheConfig,因此在Spring 3中原本必须有的value属性,也成为非必需项了 。
  2. key:缓存对象存储在Map集合中的key值,非必需,缺省按照函数的所有参数组合作为key值,若自己配置需使用SpEL表达式,比如:@Cacheable(key = “#p0”);
    使用函数第一个参数作为缓存的key值,更多关于SpEL表达式的详细内容可参考官方文档
  3. condition:缓存对象的条件,非必需,也需使用SpEL表达式,只有满足表达式条件的内容才会被缓存,比如:@Cacheable(key = “#p0”, condition = “#p0.length() < 3”);
    表示只有当第一个参数的长度小于3的时候才会被缓存,若做此配置上面的AAA用户就不会被缓存,读者可自行实验尝试。
  4. unless:另外一个缓存条件参数,非必需,需使用SpEL表达式。它不同于condition参数的地方在于它的判断时机,该条件是在函数被调用之后才做判断的,所以它可以通过对result进行判断。
  5. keyGenerator:用于指定key生成器,非必需。若需要指定一个自定义的key生成器,我们需要去实现org.springframework.cache.interceptor.KeyGenerator接口,并使用该参数来指定。需要注意的是:该参数与key是互斥的
  6. cacheManager:用于指定使用哪个缓存管理器,非必需。只有当有多个时才需要使用
  7. cacheResolver:用于指定使用那个缓存解析器,非必需。需通过
    org.springframework.cache.interceptor.CacheResolver接口来实现自己的缓存解析器,并用该参数指定。
  • @CachePut:配置于函数上,能够根据参数定义条件来进行缓存,它与@Cacheable不同的是,它每次都会真实调用函数,所以主要用于数据新增和修改操作上。它的参数与@Cacheable类似,具体功能可参考上面对@Cacheable参数的解析。

  • @CacheEvict:配置于函数上,通常用在删除方法上,用来从缓存中移除相应数据。除了同@Cacheable一样的参数之外,它还有下面两个参数:

  1. allEntries:非必需,默认为false。当为true时,会移除所有数据
  2. beforeInvocation:非必需,默认为false,会在调用方法之后移除数据。当为true时,会在调用方法之前移除数据。

下面,我们来模拟数据库的操作,并把结果缓存到Redis中


@Service
@Slf4j
@CacheConfig(cacheNames = "users")
public class RedisCacheServiceImpl implements RedisCacheService {

    @Override
    @CachePut(key = "#p0.id")
    public User save(User user) {
        log.info("-----执行数据库更新操作");
        log.info("-----数据库更新完成,返回结果");

        return user;
    }

    @Override
    @Cacheable(key = "#p0")
    public User get(String id) {
        log.info("-----执行数据库查询操作");
        User user = User.builder().id(id).name("spring").age(18).build();
        log.info("-----数据库查询完成,返回结果");
        return user;
    }

    @Override
    @CacheEvict(key = "#p0")
    public void delete(String id) {
        log.info("-----执行数据库删除操作");
        log.info("-----数据库删除完成,返回结果");
    }
}

在Junit中进行测试


@SpringBootTest
@RunWith(SpringJUnit4ClassRunner.class)
@Slf4j
public class RedisCacheServiceTest {
    @Resource
    private RedisCacheService redisCacheService;

    @Test
    public void testGet() {
        User user = redisCacheService.get("1111111");
        log.info(user.toString());
    }

    @Test
    public void testSave() {
        User user = User.builder().id("1111111").name("spring").age(20).build();
        redisCacheService.save(user);
    }

    @Test
    public void testDelete() {
        redisCacheService.delete("1111111");
    }
}

先调用get方法,此时,Redis中没有此数据,会进入方法,拿到数据之后返回,并且把数据缓存到Redis中,结果如下:


2019-05-22 10:57:57.532  INFO 42313 --- [           main] o.b.r.s.impl.RedisCacheServiceImpl       : -----执行数据库查询操作
2019-07-29 10:57:57.533  INFO 42313 --- [           main] o.b.r.s.impl.RedisCacheServiceImpl       : -----数据库查询完成,返回结果
2019-07-29 10:57:57.557  INFO 42313 --- [           main] o.b.redis.service.RedisCacheServiceTest  : User(id=1111111, name=spring, age=18)

再调用一次get方法,此时将不会进入方法中,直接从缓存中拿到数据并返回,结果如下:


2019-07-29 10:57:57.557  INFO 42313 --- [           main] o.b.redis.service.RedisCacheServiceTest  : User(id=1111111, name=spring, age=18)

再调用save方法,会把缓存中ID为1111111的User年龄更新为20,调用delete方法会删除缓存,和预期的结果一致,这里就不贴结果了,感兴趣的同学可以自行验证。redis的学习到这里暂时结束,以后用到更深入的技术再来进行探讨研究。
摘自:https://blog.csdn.net/oppo5630/article/details/80403111

你可能感兴趣的:(小白入门-Redis学习第三篇)