springboot高级特性-redis作为缓存
Posted 暴躁的程序猿啊
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了springboot高级特性-redis作为缓存相关的知识,希望对你有一定的参考价值。
springboot版本为2.5.4
redis版本 3.2
引入starter
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
配置redis
spring.redis.port=6379
spring.redis.host=localhost
导入依赖之后会在容器中为我们注入两个template帮助我们操作redis
一个是StringRedisTemplate (操做字符串的)和 RedisTemplate
使用的时候直接注入即可
常见的几个方法
字符串String list set zset hash
opsForValue() 操作字符串的
opsForList()操作list
opsForSet()操作set的
opsForHash()操作hash
opsForZset() 操作zset的 有序集合
测试redis是否连接成功
@SpringBootTest
class Springboot01CacheApplicationTests {
@Autowired
RedisTemplate redisTemplate;
@Autowired
StringRedisTemplate stringRedisTemplate;
/**
* 字符串String list set zset hash
* opsForValue() 操作字符串的
* opsForList()操作list
* opsForSet()操作set的
* opsForHash()操作hash
* opsForZset() 操作zset的 有序集合
*/
public void test01(){
//往redis中保存数据
stringRedisTemplate.opsForValue().set("message","abc");
}
}
测试结果
测试redis序列化对象
因为我们存储对象到redis时 redis默认的是jdk序列化方式 与我们想要的json等格式有一些区别 所以我们 需要自己指定redis的序列化方式 我们 创建一个配置类 设置 redis的序列化器
@Configuration
public class MyRedisConfig {
@Bean
public RedisTemplate<String, Employee> myRedisTemplate(
RedisConnectionFactory redisConnectionFactory)
throws UnknownHostException {
RedisTemplate<String, Employee> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory);
// 使用Jackson2JsonRedisSerialize 替换默认序列化
Jackson2JsonRedisSerializer<Object> serializer = new Jackson2JsonRedisSerializer<>(Object.class);
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
objectMapper.activateDefaultTyping(objectMapper.getPolymorphicTypeValidator(),ObjectMapper.DefaultTyping.NON_FINAL);
serializer.setObjectMapper(objectMapper);
// 设置value的序列化规则和 key的序列化规则
template.setKeySerializer(new StringRedisSerializer());
template.setValueSerializer(serializer);
template.setHashKeySerializer(new StringRedisSerializer());
template.setHashValueSerializer(serializer);
template.afterPropertiesSet();
return template;
}
}
测试
@Test
public void test02(){
Employee empById = employeeMapper.getEmpById(1);
System.out.println(empById);
myRedisTemplate.opsForValue().set("emp",empById);
Employee emp = myRedisTemplate.opsForValue().get("emp");
System.out.println(emp);
}
数据库中的数据
整合缓存
boot中的CacheManager缓存管理器 帮我们创建缓存组件 缓存组件实际为我们缓存数据
当我们引入了redis Starter后 会在我们容器中放入一个 RedisCacheManager 缓存管理器 这时我们默认的SimpleCacheConfiguration就会失效 因为 SimpleCacheConfiguration的判断条件是缓存中没有CacheManager的情况下生效 我们的Redis放入了一个 RedisCacheManager 就会让我们的SimpleCache失效
ReidsCacheManager帮我们创建RedisCache来作为缓存组件 RedisCache通过操作redis缓存数据
所以说我们直接测试就可以了
我们的pojo类
注意实现Serializable 接口 不然不能序列化
@Data
public class Employee implements Serializable {
private Integer id;
private String lastName;
private String email;
private Integer gender; //性别 1男 0女
}
mapper
@Mapper
public interface EmployeeMapper {
@Select("select * from employee where id =#{id}")
public Employee getEmpById(Integer id);
@Select("select * from employee where lastName=#{lastName}")
public Employee getEmpByLastName(String lastName);
}
service
在service层配置缓存注解 使用缓存注解需要在启动类上加@@EnableCaching
@CacheConfig(cacheNames = "emp")
@Service
public class EmployeeService {
@Autowired
EmployeeMapper employeeMapper;
@Cacheable(cacheNames = "emp",condition = "#id>0")
public Employee getEmp(Integer id){
System.out.println("查询"+id+"号员工");
Employee empById = employeeMapper.getEmpById(id);
return empById;
}
}
controller
@RestController
public class EmployeeController {
@Autowired
EmployeeService employeeService;
@GetMapping("/emp/{id}")
public Employee getEmployee(@PathVariable("id")Integer id){
Employee emp = employeeService.getEmp(id);
return emp;
}
}
我们先进行第一次查询数据
访问http://localhost:8080/emp/1
我们发现访问了数据库
这时候我们清空控制台再进行一次访问发现没有查询数据库 肯定是redis帮我们缓存起来了
这是候我们查看redis发现多了一个缓存数据
我们取出数据看看
127.0.0.1:6379> get emp::1
"\\xac\\xed\\x00\\x05sr\\x00\\x1bcom.rpf.cache.bean.EmployeePU2z\\x98\\xeat\\xc9\\x02\\x00\\x05L\\x00\\x03dIdt\\x00\\x13Ljava/lang/Integer;L\\x00\\x05emailt\\x00\\x12Ljava/lang/String;L\\x00\\x06genderq\\x00~\\x00\\x01L\\x00\\x02idq\\x00~\\x00\\x01L\\x00\\blastNameq\\x00~\\x00\\x02xpsr\\x00\\x11java.lang.Integer\\x12\\xe2\\xa0\\xa4\\xf7\\x81\\x878\\x02\\x00\\x01I\\x00\\x05valuexr\\x00\\x10java.lang.Number\\x86\\xac\\x95\\x1d\\x0b\\x94\\xe0\\x8b\\x02\\x00\\x00xp\\x00\\x00\\x00\\x01t\\x00\\x0e2858458@qq.comq\\x00~\\x00\\x06q\\x00~\\x00\\x06t\\x00\\x06\\xe7\\x8e\\x8b\\xe4\\xba\\x94"
发现使用序列化的方式保存的
默认保存数据 k-v都是Object 的时候;利用序列化来保存的
我们需要更改CacheManager 使用Json的方式缓存
在配置类中添加配置
@Configuration
public class MyRedisConfig {
//配置Redistemplate
@Bean
public RedisTemplate<String, Object> myRedisTemplate(
RedisConnectionFactory redisConnectionFactory)
throws UnknownHostException {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory);
// 使用Jackson2JsonRedisSerialize 替换默认序列化
Jackson2JsonRedisSerializer<Object> serializer = new Jackson2JsonRedisSerializer<>(Object.class);
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
objectMapper.activateDefaultTyping(objectMapper.getPolymorphicTypeValidator(),ObjectMapper.DefaultTyping.NON_FINAL);
serializer.setObjectMapper(objectMapper);
// 设置value的序列化规则和 key的序列化规则
template.setKeySerializer(new StringRedisSerializer());
template.setValueSerializer(serializer);
template.setHashKeySerializer(new StringRedisSerializer());
template.setHashValueSerializer(serializer);
template.afterPropertiesSet();
return template;
}
//使用CacheManager缓存
@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.activateDefaultTyping(om.getPolymorphicTypeValidator(),ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
// 配置序列化(解决乱码的问题),过期时间30秒
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofSeconds(1800000))
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer))
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer))
.disableCachingNullValues();
RedisCacheManager cacheManager = RedisCacheManager.builder(factory)
.cacheDefaults(config)
.build();
return cacheManager;
}
}
配置完成重新测试
发现缓存成功
redis中以json格式缓存了值
以上是关于springboot高级特性-redis作为缓存的主要内容,如果未能解决你的问题,请参考以下文章
golang常用库包:缓存redis操作库go-redis使用(03)-高级数据结构和其它特性
分布式缓存技术redis学习系列——redis高级应用(集群搭建集群分区原理集群操作)