整合redis
- springboot在现在的版本中操作Redis数据库用到了lettuce,而不是Jedis,他们各有各的特点。
- Jedis以Redis命令作为方法名称,学习成本低,简单实用。但是Jedis实例是线程不安全的,多线程环境下需要基于连接池来使用。
- Lettuce是基于Netty实现的,支持同步、异步和响应式编程方式,并且是线程安全的。支持Redis的哨兵模式、集群模式和管道模式。
SpringDataRedis相关的api
1、引入依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
2、配置文件
spring:redis:# Redis服务器地址host: 127.0.0.1# Redis服务器端口号port: 6379# 使用的数据库索引,默认是0database: 0# 连接超时时间timeout: 1800000# 设置密码password: "123456"
3、代码测试
@Autowiredprivate RedisTemplate redisTemplate;@Testpublic void redis() {redisTemplate.opsForValue().set("study","学习redis");String name = (String) redisTemplate.opsForValue().get("study");System.out.println(name); }
问题出现了:当我们使用Redis客户端查看刚刚存入Redis数据库的数据时,结果是这样的:
是因为在使用默认的对象redisTemplate时,会把value值序列化为byte类型,所以就出现了上图的结果。
同理,如果我们存储内容是对象的时候,不序列化的话会报错
因此我们需要自定义序列化器
public void redis(){User user = new User();user.setName("zs");user.setDeptId("11");user.setAge(20);redisTemplate.opsForValue().set("user:info",user);}
报错:
因此我们需要自定义序列化器
4、自定义序列化器
@Configuration
public class RedisCacheManagerConfig {@Beanpublic RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {RedisTemplate<String, Object> template = new RedisTemplate<>();template.setConnectionFactory(factory);// 设置Key的序列化方式template.setKeySerializer(new StringRedisSerializer());// 设置Value的序列化方式,根据需求选择template.setValueSerializer(jackson2JsonRedisSerializer());// 同样可以设置hashKey和hashValue的序列化方式template.setHashKeySerializer(new StringRedisSerializer());template.setHashValueSerializer(new Jackson2JsonRedisSerializer<>(Object.class));return template;}// 配置Jackson2JsonRedisSerializer// 避免出现获取缓存时出现的类型转换错误private Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer() {Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer =new Jackson2JsonRedisSerializer<>(Object.class);ObjectMapper objectMapper = new ObjectMapper();objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);objectMapper.configure(MapperFeature.USE_ANNOTATIONS, false);objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);// 此项必须配置,否则会报java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to XXXobjectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);jackson2JsonRedisSerializer.setObjectMapper(objectMapper);return jackson2JsonRedisSerializer;}}
再次执行存储对象,存储字符串
整合redisCahemanager
在上述redis配置中增加cacheMangerp配置
@Configuration
public class RedisCacheManagerConfig {@Beanpublic CacheManager cacheManager(RedisConnectionFactory connectionFactory) {// 若想存入的不包含类信息,就直接使用GenericJackson2JsonRedisSerializer,配合ObjectMapperObjectMapper objectMapper = new ObjectMapper(); GenericJackson2JsonRedisSerializer serializer = new GenericJackson2JsonRedisSerializer(objectMapper);//------------------------//RedisCacheConfiguration cacheConfiguration = RedisCacheConfiguration.defaultCacheConfig().serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer()))//变双冒号为单冒号.computePrefixWith(name -> name +":");return RedisCacheManager.builder(connectionFactory).cacheDefaults(cacheConfiguration).build();}@Beanpublic RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {RedisTemplate<String, Object> template = new RedisTemplate<>();template.setConnectionFactory(factory);// 设置Key的序列化方式template.setKeySerializer(new StringRedisSerializer());// 设置Value的序列化方式,根据需求选择template.setValueSerializer(jackson2JsonRedisSerializer());// 同样可以设置hashKey和hashValue的序列化方式template.setHashKeySerializer(new StringRedisSerializer());template.setHashValueSerializer(new Jackson2JsonRedisSerializer<>(Object.class));return template;}// 配置Jackson2JsonRedisSerializer// 避免出现获取缓存时出现的类型转换错误private Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer() {Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer =new Jackson2JsonRedisSerializer<>(Object.class);ObjectMapper objectMapper = new ObjectMapper();objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);objectMapper.configure(MapperFeature.USE_ANNOTATIONS, false);objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);// 此项必须配置,否则会报java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to XXXobjectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);jackson2JsonRedisSerializer.setObjectMapper(objectMapper);return jackson2JsonRedisSerializer;}}
使用参考springCache本地缓存:
SpringCache之本地缓存-CSDN博客
简单测试:
@Component
public class UserCache {@Cacheable(cacheNames = "room")public User getUserId(String userId){User user = new User();user.setId(userId);user.setAge(10);user.setDeptId("1");user.setName("zs");user.setSex("男");return user;}
}@Autowiredprivate UserCache userCache;@Testpublic void cache(){User user = userCache.getUserId("1");System.out.println(user);}
结果: