1、搭建环境
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
2、使用
springboot封装了两个操作redis的对象,因为使用中String类型使用比较多,所以封装了StringRedisTemplate是专门操作k-v都是字符串的;RedisTemplate用来操作对象。
@Autowired
StringRedisTemplate stringRedisTemplate;
@Autowired
RedisTemplate redisTemplate;
public void test01(){
stringRedisTemplate.opsForValue().append("msg","hello");
redisTemplate.opsForValue().set("emp-01",empById);
使用时,需要在模板对象后调用opsForXXX()方法装换操作数据类型
stringRedisTemplate.opsForValue()[String(字符串)]
stringRedisTemplate.opsForList()[List(列表)]
stringRedisTemplate.opsForSet()[Set(集合)]
stringRedisTemplate.opsForHash()[Hash(散列)]
stringRedisTemplate.opsForZSet()[ZSet(有序集合)]
3、redis中编码保存数据
(1)、如果保存对象,默认使用jdk序列化机制,序列化后的数据保存到redis中
@Test
public void contextLoad() {
Employee zhangsan = new Employee(1, "zhangsan", "w45645@qq.com", 1, 1);
redisTemplate.opsForValue().set("职员1",zhangsan);
}
(2)但这样不利于阅读,可以将数据以json的方式保存。
方式一:将数据人为转为json字符串后保存。
方拾二:改变redisTemplate默认的序列化规则
(3)改变redisTemplate默认序列化规则
原始序列化规则是new了一个JdkSerializationRedisSerializer,即默认使用jdk序列化个规则。
public void afterPropertiesSet() {
super.afterPropertiesSet();
boolean defaultUsed = false;
if (this.defaultSerializer == null) {
this.defaultSerializer = new JdkSerializationRedisSerializer(this.classLoader != null ? this.classLoader : this.getClass().getClassLoader());
}
改变规则只需要在redisTemplate对象中调用defaultSerializer的set方法,改变序列化器,再使用中调用自定义序列化器即可。
@Configuration
public class MySerizlizeble {
@Bean
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<Object, Object> template = new RedisTemplate();
template.setConnectionFactory(redisConnectionFactory);
template.setDefaultSerializer(new Jackson2JsonRedisSerializer<Object>(Object.class));
return template;
}
}
@Autowired
private RedisTemplate<Object,Object> myredis;
@Test
public void contextLoad() {
Employee zhangsan = new Employee(1, "zhangsan", "w45645@qq.com", 1, 1);
myredis.opsForValue().set("职员1",zhangsan);
}
最终结果:
4、使用注解操作数据
(1)、引入Redis的starter后,在建立CacheManager
时Redis的判定先与SimpleCacheManager
,所以CacheConfiguration
为容器注入了一个RedisCacheManager
,由于此后容器中已经存在了一个Manager,所以后续的其他缓存配置类就不会再生效了。并在Manager加载缓存时,如果缓存不存在,就会创建一个缓存Cache组件。
@Bean
RedisCacheManager cacheManager(CacheProperties cacheProperties, CacheManagerCustomizers cacheManagerCustomizers, ObjectProvider<org.springframework.data.redis.cache.RedisCacheConfiguration> redisCacheConfiguration, ObjectProvider<RedisCacheManagerBuilderCustomizer> redisCacheManagerBuilderCustomizers, RedisConnectionFactory redisConnectionFactory, ResourceLoader resourceLoader) {
RedisCacheManagerBuilder builder = RedisCacheManager.builder(redisConnectionFactory).cacheDefaults(this.determineConfiguration(cacheProperties, redisCacheConfiguration, resourceLoader.getClassLoader()));
List<String> cacheNames = cacheProperties.getCacheNames();
protected Collection<RedisCache> loadCaches() {
List<RedisCache> caches = new LinkedList();
Iterator var2 = this.initialCacheConfiguration.entrySet().iterator();
while(var2.hasNext()) {
Entry<String, RedisCacheConfiguration> entry = (Entry)var2.next();
caches.add(this.createRedisCache((String)entry.getKey(), (RedisCacheConfiguration)entry.getValue()));
}
return caches;
}
(2)、但是由于创建RedisCacheManager使用默认的jdk序列化机制,所以保存为json仍需要自定义CacheManager。
由于springboot2.x版本定义如下:
private RedisCacheManager(RedisCacheWriter cacheWriter, RedisCacheConfiguration defaultCacheConfiguration, boolean allowInFlightCacheCreation) {}
public RedisCacheManager(RedisCacheWriter cacheWriter, RedisCacheConfiguration defaultCacheConfiguration) {}
public RedisCacheManager(RedisCacheWriter cacheWriter, RedisCacheConfiguration defaultCacheConfiguration, String... initialCacheNames) {}
public RedisCacheManager(RedisCacheWriter cacheWriter, RedisCacheConfiguration defaultCacheConfiguration, boolean allowInFlightCacheCreation, String... initialCacheNames) {}
public RedisCacheManager(RedisCacheWriter cacheWriter, RedisCacheConfiguration defaultCacheConfiguration, Map<String, RedisCacheConfiguration> initialCacheConfigurations) {}
public RedisCacheManager(RedisCacheWriter cacheWriter, RedisCacheConfiguration defaultCacheConfiguration, Map<String, RedisCacheConfiguration> initialCacheConfigurations, boolean allowInFlightCacheCreation) {}
RedisCacheManager构造方法一共有六种,此处选择参数较少的进行定义:
public RedisCacheManager(RedisCacheWriter cacheWriter, RedisCacheConfiguration defaultCacheConfiguration) {}
(a)根据带参构造,需要两个参数RedisCacheWriter
和RedisCacheConfiguration
,RedisCacheWriter
是一个接口,所以选择获取它的实现类DefaultRedisCacheWriter
来创建对象,通过它可以完成缓存的读写工作。
public interface RedisCacheWriter extends CacheStatisticsProvider {
static RedisCacheWriter nonLockingRedisCacheWriter(RedisConnectionFactory connectionFactory) {
Assert.notNull(connectionFactory, "ConnectionFactory must not be null!");
return new DefaultRedisCacheWriter(connectionFactory);
}
RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(connectionFactory);
(b)、创建RedisCacheConfiguration
对象
根据RedisCacheConfiguration
中的静态方法defaultCacheConfig
使用了注解@Nullable
注解,即参数可以为空,所以调用这个方法可以得到RedisCacheConfiguration
对象。
public static RedisCacheConfiguration defaultCacheConfig() {
return defaultCacheConfig((ClassLoader)null);
}
public static RedisCacheConfiguration defaultCacheConfig(@Nullable ClassLoader classLoader) {
DefaultFormattingConversionService conversionService = new DefaultFormattingConversionService();
registerDefaultConverters(conversionService);
return new RedisCacheConfiguration(Duration.ZERO, true, true, CacheKeyPrefix.simple(), SerializationPair.fromSerializer(RedisSerializer.string()), SerializationPair.fromSerializer(RedisSerializer.java(classLoader)), conversionService);
}
(c)、定义序列化的规则
调用serializeValuesWith
方法向RedisCacheConfiguration
中注入序列化的规则。
public RedisCacheConfiguration serializeValuesWith(SerializationPair<?> valueSerializationPair) {
Assert.notNull(valueSerializationPair, "ValueSerializationPair must not be null!");
return new RedisCacheConfiguration(this.ttl, this.cacheNullValues, this.usePrefix, this.keyPrefix, this.keySerializationPair, valueSerializationPair, this.conversionService);
}
(d)上述的方法中需要一个参数SerializationPair
,而SerializationPair
是一个RedisSerializationContext
接口内部定义的一个接口,无法实例化,故也需要通过实现类传入序列化规则实例化。
public interface SerializationPair<T> {
static <T> RedisSerializationContext.SerializationPair<T> fromSerializer(RedisSerializer<T> serializer) {
Assert.notNull(serializer, "RedisSerializer must not be null!");
return new RedisSerializerToSerializationPairAdapter(serializer);
}
综上,可以得到代码:
@Bean
public RedisCacheManager myCacheManager(RedisConnectionFactory connectionFactory){
//获取RedisCacheWriter 对象,可以实现
RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(connectionFactory);
//定义序列化规则为Jackson2JsonRedisSerializer
Jackson2JsonRedisSerializer<Object> Jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
//获取SerializationPair对象,封装序列化规则
RedisSerializationContext.SerializationPair<Object> objectSerializationPair = RedisSerializationContext.SerializationPair.fromSerializer(Jackson2JsonRedisSerializer);
//获取RedisCacheConfiguration ,并注入序列化规则。
RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig().serializeValuesWith(objectSerializationPair);
//创建RedisCacheManager
RedisCacheManager redisCacheManager = new RedisCacheManager(redisCacheWriter,redisCacheConfiguration);
return redisCacheManager;
}
最终效果:
此处did为null是因为未开启驼峰命名法。开启驼峰命名法如下:
mybatis:
configuration:
map-underscore-to-camel-case: true