引言
java操作Redis有很多中方案,Jedis,SpringBootDataRedis,Redisson等,本篇文章的目的是使用SpringBootDataRedis整合SpringCache基于Redis实现缓存操作
一、SpringBoot整合Redis实现缓存
SpringBoot提供了整合Redis的方案,我们使用spring-boot-starter-data-redis包就可以很方便的操作Redis了。
1.第一步:导入redis的基础依赖
XML
<!--整合Redis , 底层可以用jedis-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<exclusions>
<exclusion>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
spring-boot-starter-data-redis 默认使用的是lettuce操作Redis,这个技术在高并发下会有内存溢出的风险,这里我排除掉lettuce,使用jedis操作redis
2.第二步:配置redis
java
spring:
redis:
database: 0
host: 127.0.0.1
port: 6379
password: 123456
jedis:
pool: #连接池
max-wait: 2000ms #等待超时
min-idle: 2 #最小空闲数
max-idle: 8 #最大空闲数
3.第三步:配置RedisTemplate序列化方式
主要配置对象存储到Redis使用JSON格式序列化,这种格式比较通用
java
@Configuration
public class CacheConfig extends CachingConfigurerSupport {
@Resource
private RedisConnectionFactory factory;
//使用JSON进行序列化
@Bean
public RedisTemplate<String, Object> redisTemplate() {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(factory);
//JSON格式序列化
GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
//value的序列化
redisTemplate.setValueSerializer(genericJackson2JsonRedisSerializer);
//hash结构value的虚拟化
redisTemplate.setHashValueSerializer(genericJackson2JsonRedisSerializer);
return redisTemplate;
}
@Bean
@Override
public CacheResolver cacheResolver() {
return new SimpleCacheResolver(cacheManager());
}
@Bean
@Override
public CacheErrorHandler errorHandler() {
// 用于捕获从Cache中进行CRUD时的异常的回调处理器。
return new SimpleCacheErrorHandler();
}
//缓存管理器
@Bean
@Override
public CacheManager cacheManager() {
RedisCacheConfiguration cacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
.disableCachingNullValues() //不允许空值
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()));//值使用JSON虚拟化
return RedisCacheManager.builder(factory).cacheDefaults(cacheConfiguration).build();
}
}
4.第三步:缓存流程
通过注入:RedisTemplate操作缓存,如果使用String的话也可以直接使用 StringRedisTemplate
java
@Autowired
private RedisTemplate<String,Object> redisTemplate;
//@Autowired
//private StringRedisTemplate stringRedisTemplate;
缓存逻辑伪代码,先从缓存查询,如果缓存有直接返回结果,如果缓存没有就走数据库查询,然后同步到缓存再返回结果:
java
public User selectUserById(Long id){
//从缓存查询
String userKey = "user:"+id;
User userFromCache = redisTemplate.opsForValue().get(userKey );
if(null == userFromCache ){
//缓存为空,从数据库查询
User userFromDB = userDao.selectUserById(id);
//把user存储到缓存
redisTemplate.opsForValue().set(userKey ,userFromDB );
//返回User
return userFromDB ;
}
return userFromCache ;
}
上面代码并不完整,在数据库中的数据发送事务操作的时候,还需要把缓存中的数据剔除来保证数据一致性
java
public void deleteUserById(Long id){
userDao.deleteUserById(id);
String userKey = "user:"+id;
redisTemplate.delete(userKey )
}
二.使用SpringCahe注解实现缓存
1.注解介绍
对于缓存声明,Spring的缓存提供了一组java注解:
- @Cacheable :写入缓存
- @CacheEvict:清除缓存
- @CachePut:更新缓存
- @Caching:组合多个缓存操作
- @CacheConfig:设置类级别上共享的一些常见缓存设置
2.开启SpringCache
在启动类贴上 @EnableCaching
注解
java
@SpringBootApplication
@EnableCaching
public class Application {
public static void main(String[] args) {
SpringApplication.run(CourseApplication.class );
}
}
3.写入缓存
@Cacheable :写入缓存,打在有返回值的方法上,自动把返回值加入缓存,并且在执行方法之前会检查缓存时候有数据,如果有就直接返回缓存中的数据,不再执行方法
java
//@Cacheable(cacheNames = "user",key = "'id1'")
@Cacheable(cacheNames = "user",key = "#id")
public User selectUserById(Long id) {
return userDao.selectUserById(id);
}
一个注解就实现了上面代码 1.4 中的缓存案例 ,非常方便,这里的:
- cacheNames = "user" :指的是缓存的名字为"user"
- key = "#id" :是值把参数id的值作为是缓存的key,"#id"是表达式写法,在Redis中会 cacheNames 和 key 联合起来作为 键 ,效果如:"user::1"
常见的用法:
- @Cacheable(cacheNames = "user",key = "'id1'") :固定一个key 效果如:"user:id1"
- @Cacheable(cacheNames = "user",key = "#obj.id") :取参数obj对象的id的值作为key ,效果如:"user::1"
- @Cacheable(cacheNames = "user",key = "#id",condition="#id > 10") : 需要满足id大于10才做缓存
4.删除缓存
在数据库做了事务操作(增删改),需要把缓存中的数据删除,等待下一次查询重新同步缓存数据,在SpringCache中可以使用 @CacheEvict
注解完成,他会主动匹配key完成缓存的剔除工作
java
@CacheEvict(cacheNames = "user",key = "#id")
public void deleteUserById(Long id){
userDao.deleteUserById(id);
}
如果要对缓存批量删除可以使用 @CacheEvict(cacheNames="user", allEntries=true)
5.更新缓存
更新缓存使用@CachePut
注解,和@Cacheable用法相同,他会把方法的返回值自动更新到缓存,以注解的key做自动匹配
java
@CachePut(cacheNames = "user",key = "#user.id")
public User updateUserById(User user){
userDao.updateUserById(user);
return user;
}
注意:建议不要把@CachePut和@Cacheable作用于同一个方法,可能会有功能上的冲突
6.组合操作
@Caching注解可以组合多个缓存操作,比如删除多个缓存
java
//删除多个缓存,user和其账户一起删除
@Caching(evict = { @CacheEvict(cacheNames="user", key = "#user.id"), @CacheEvict(cacheNames="account", key = "#user.id") })
public void updateUserById(User user){
userDao.updateUserById(user);
return user;
}
7.公共配置
@CacheConfig注解可以配置一些共享的属性,比如把cacheNames抽取出来
java
@CacheConfig(cacheName="user")
public class CacheService{
@CacheEvict(key = "#id")
public void deleteUserById(Long id){
userDao.deleteUserById(id);
}
@CachePut(key = "#user.id")
public User updateUserById(User user){
userDao.updateUserById(user);
return user;
}
}
文章结束啦,如果对你有帮助请一定给个好评哦~~~