springboot与redis整合中@Cacheable怎么使用

首先我们需要配置一个缓存管理器,然后才能使用缓存注解来管理缓存

package com.cherish.servicebase.handler;


import com.fasterxml.jackson.annotation.JsonAutoDetect;

import com.fasterxml.jackson.annotation.PropertyAccessor;

import com.fasterxml.jackson.databind.ObjectMapper;

import org.springframework.cache.CacheManager;

import org.springframework.cache.annotation.CachingConfigurerSupport;

import org.springframework.cache.annotation.EnableCaching;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

import org.springframework.data.redis.cache.RedisCacheConfiguration;

import org.springframework.data.redis.cache.RedisCacheManager;

import org.springframework.data.redis.connection.RedisConnectionFactory;

import org.springframework.data.redis.core.RedisTemplate;

import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;

import org.springframework.data.redis.serializer.RedisSerializationContext;

import org.springframework.data.redis.serializer.RedisSerializer;

import org.springframework.data.redis.serializer.StringRedisSerializer;


import java.time.Duration;


@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {
@Bean
public RedisTemplate<
String, Object>
redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<
String, Object>
template = new RedisTemplate<
>
();

RedisSerializer<
String>
redisSerializer = new StringRedisSerializer();

Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);

ObjectMapper om = new ObjectMapper();

om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);

om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);

jackson2JsonRedisSerializer.setObjectMapper(om);

template.setConnectionFactory(factory);

//key序列化方式
template.setKeySerializer(redisSerializer);

//value序列化
template.setValueSerializer(jackson2JsonRedisSerializer);

//value hashmap序列化
template.setHashValueSerializer(jackson2JsonRedisSerializer);

return template;

}

@Bean
public CacheManager cacheManager(RedisConnectionFactory factory) {
RedisSerializer<
String>
redisSerializer = new StringRedisSerializer();

Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);

//解决查询缓存转换异常的问题
ObjectMapper om = new ObjectMapper();

om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);

om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);

jackson2JsonRedisSerializer.setObjectMapper(om);

// 配置序列化(解决乱码的问题),过期时间600秒
RedisCacheConfiguration config = RedisCacheConfiguration
.defaultCacheConfig()
.entryTtl(Duration.ofSeconds(600))
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer))
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer))
.disableCachingNullValues();


RedisCacheManager cacheManager = RedisCacheManager.builder(factory)
.cacheDefaults(config)
// 可以给每个cacheName不同的RedisCacheConfiguration 设置不同的过期时间
//.withCacheConfiguration("
Users"
,config.entryTtl(Duration.ofSeconds(100)))
.transactionAware()
.build();

return cacheManager;

}
} 1、@Cacheable

标记在方法或者类上,标识该方法或类支持缓存。Spring调用注解标识方法后会将返回值缓存到redis,以保证下次同条件调用该方法时直接从缓存中获取返回值。这样就不需要再重新执行该方法的业务处理过程,提高效率。

@Cacheable常用的三个参数如下:

cacheNames 缓存名称key 缓存的key,需要注意key的写法哈condition 缓存执行的条件,返回true时候执行

示例

//查询所有用户,缓存到redis中
@GetMapping("
/selectFromRedis"
)
@Cacheable(cacheNames = "
Users"
,key = "
'
user'
"
)
public ResultData getUserRedis(){
List<
User>
list = userService.list(null);

return ResultData.ok().data("
User"
,list);

}

第一次查询是从数据库查询的,然后缓存到redis中 使用redis可视化工具查看缓存的信息

第二查询走了缓存控制台没有输出 ,所以走的redis缓存 就是在redis中获取结果直接返回。

@CacheEvict

标记在方法上,方法执行完毕之后根据条件或key删除对应的缓存。常用的属性:

  • allEntries boolean类型,表示是否需要清除缓存中的所有元素

  • SpringBoot与Redis整合,利用@Cacheable作缓存

    key 需要删除的缓存的key

//调用这个接口结束后,删除指定的Redis缓存
@PostMapping("
updateUser"
)
@CacheEvict(cacheNames ="
Users"
,key = "
'
user'
"
)
public ResultData updateUser(@RequestBody User user){
String id = user.getId();

QueryWrapper<
User>
wrapper=new QueryWrapper<
>
();

wrapper.eq("
id"
,id);

boolean b = userService.update(user, wrapper);

return ResultData.ok().data("
flag"
,b);

} //不删除redis缓存
@PostMapping("
updateUser2"
)
public ResultData updateUser2(@RequestBody User user){
String id = user.getId();

QueryWrapper<
User>
wrapper=new QueryWrapper<
>
();

wrapper.eq("
id"
,id);

boolean b = userService.update(user, wrapper);

return ResultData.ok().data("
flag"
,b);

}

当我们更新数据库的数据时候,需要把redis的缓存清空。否则我们查询的数据是redis缓存中的数据,这样就会导致数据库和缓存数据不一致的问题。

示例 调用没有加 @CacheEvict 注解的接口修改数据,在查询得到的数据是未修改之前的。

所以在我们调用修改数据的接口的时候需要清除缓存

加上 @CacheEvict 注解 清除对应的缓存此时在查询数据发现数据是最新的,跟数据库保持一致。

过期时间

我们已经实现了Spring Cache的基本功能,整合了Redis作为RedisCacheManger,但众所周知,我们在使用@Cacheable注解的时候是无法给缓存这是过期时间的。但有时候在一些场景中我们的确需要给缓存一个过期时间!这是默认的过期时间

数据有效期时间

自定义过期时间

使用新的redis配置,再次查询缓存到数据看数据有效期



SpringBoot作为一个高效的Web应用框架,在开发中为我们提供了很多便利。而Redis则作为一个高性能的NoSql数据库,被广泛应用于缓存中性能的优化。
一、@Cacheable的概述
在Spring框架的众多注解中,有一个用于缓存的注解@Cacheable。它可以将一个方法的返回值进行缓存,缓存的key值就是方法的参数值,这样能够很好地提高程序的性能。
二、@Cacheable的使用步骤
使用@Cacheable注解需要进行如下几个步骤:
1. 在pom.xml文件中添加redis的依赖
2. 在SpringBoot的配置文件application.yml中配置redis连接信息
3. 在需要进行缓存的方法上添加@Cacheable注解
三、@Cacheable的使用示例
下面我们以查询用户详细信息的方法为例:
```
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserRepository userRepository;
@Override
@Cacheable(value = \"userCache\", key = \"#userId\")
public UserDTO getUserDetail(Long userId) {
User user = userRepository.findById(userId).orElseThrow(() -> new EntityNotFoundException(\"User not found\"));
return UserDTO.builder()
.id(user.getId())
.username(user.getUsername())
.email(user.getEmail())
.build();
}
}
```
这个方法在执行时会自动进行缓存,如果下次查询相同的用户id,将会直接从缓存中查询,缩短了数据库的查询时间,提高了程序的性能。
四、注意事项
使用@Cacheable注解需要注意以下几个点:
1. 缓存的value值需与CacheManager的cacheNames一致
2. 方法的参数值作为缓存的key值,需要重写方法的hashCode和equals方法
3. 在更新操作后需要主动清空缓存,避免脏数据的出现。