学习使用,老鸟飞过,欢迎交流
java操作Redis有很多中方案,Jedis,SpringBootDataRedis,Redisson等,本篇文章的目的是使用SpringBootDataRedis整合SpringCache基于Redis实现缓存操作
SpringBoot提供了整合Redis的方案,我们使用spring-boot-starter-data-redis包就可以很方便的操作Redis了。
<!--整合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
spring:
redis:
database: 0
host: 127.0.0.1
port: 6379
password: 123456
jedis:
pool: #连接池
max-wait: 2000ms #等待超时
min-idle: 2 #最小空闲数
max-idle: 8 #最大空闲数
主要配置对象存储到Redis使用JSON格式序列化,这种格式比较通用
@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();
}
}
通过注入:RedisTemplate操作缓存,如果使用String的话也可以直接使用 StringRedisTemplate
@Autowired
private RedisTemplate<String,Object> redisTemplate;
//@Autowired
//private StringRedisTemplate stringRedisTemplate;
缓存逻辑伪代码,先从缓存查询,如果缓存有直接返回结果,如果缓存没有就走数据库查询,然后同步到缓存再返回结果:
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 ;
}
上面代码并不完整,在数据库中的数据发送事务操作的时候,还需要把缓存中的数据剔除来保证数据一致性
public void deleteUserById(Long id){
userDao.deleteUserById(id);
String userKey = "user:"+id;
redisTemplate.delete(userKey )
}
对于缓存声明,Spring的缓存提供了一组java注解:
在启动类贴上 @EnableCaching
注解
@SpringBootApplication
@EnableCaching
public class Application {
public static void main(String[] args) {
SpringApplication.run(CourseApplication.class );
}
}
@Cacheable :写入缓存,打在有返回值的方法上,自动把返回值加入缓存,并且在执行方法之前会检查缓存时候有数据,如果有就直接返回缓存中的数据,不再执行方法
//@Cacheable(cacheNames = "user",key = "'id1'")
@Cacheable(cacheNames = "user",key = "#id")
public User selectUserById(Long id) {
return userDao.selectUserById(id);
}
一个注解就实现了上面代码 1.4 中的缓存案例 ,非常方便,这里的
常见的用法:
在数据库做了事务操作(增删改),需要把缓存中的数据删除,等待下一次查询重新同步缓存数据,在SpringCache中可以使用 @CacheEvict
注解完成,他会主动匹配key完成缓存的剔除工作
@CacheEvict(cacheNames = "user",key = "#id")
public void deleteUserById(Long id){
userDao.deleteUserById(id);
}
如果要对缓存批量删除可以使用 @CacheEvict(cacheNames="user", allEntries=true)
更新缓存使用@CachePut
注解,和@Cacheable用法相同,他会把方法的返回值自动更新到缓存,以注解的key做自动匹配
@CachePut(cacheNames = "user",key = "#user.id")
public User updateUserById(User user){
userDao.updateUserById(user);
return user;
}
注意:建议不要把@CachePut和@Cacheable作用于同一个方法,可能会有功能上的冲突
@Caching注解可以组合多个缓存操作,比如删除多个缓存
//删除多个缓存,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;
}
@CacheConfig注解可以配置一些共享的属性,比如把cacheNames抽取出来
@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;
}
}
文章结束,希望对你有所帮助
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://blog.csdn.net/u014494148/article/details/110426771
内容来源于网络,如有侵权,请联系作者删除!