Redis 简介
REmote DIctionary Server\(Redis\) 是一个由Salvatore Sanfilippo写的key-value存储系统。Redis是一个开源的
使用ANSI C语言编写、遵守BSD协议、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。它通
常被称为数据结构服务器,因为值(value)可以是 字符串(String), 哈希(Map), 列表(list), 集合(sets) 和 有序集合
(sorted sets)等类型。
Redis 优势
性能极高 – Redis能读的速度是110000次/s,写的速度是81000次/s 。
丰富的数据类型 – Redis支持二进制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 数据类型操作。
原子 – Redis的所有操作都是原子性的,意思就是要么成功执行要么失败完全不执行。单个操作是原子性的。多个操作也支持事务,即原子性,
通过MULTI和EXEC指令包起来。丰富的特性 – Redis还支持 publish/subscribe, 通知, key 过期等等特性。
采用了spring-data-redis(以下简称SDR)中的Template进行redis的操作。
因为考虑到后期的使用场景,于是同时采用了StringRedisTemplate和RedisTemplate,
并且对存储String与存储Java对象采用不同的Template进行了简单的封装。
首先是测试 保存与取出方法。分别用不同的template可以完美通过。
然后在测试删除的方法中,测试出现了问题。
问题如下:
在采用StringRedisTemplate进行保存的数据,用StringRedisTemplate去删除可以成功删除。
在采用RedisTemplate进行保存的数据,用RedisTemplate去删除也可以删除成功。
在用RedisTemplate去删除StringRedisTemplate保存的数据时,发现删除失败。
在用StringRedisTemplate去删除RedisTemplate保存的数据时,删除失败。
因为,需要封装一套通用的删除方法,并且需要封装一个批量删除的方法。所以研究了下问题出现的原因。
经过查看SDR官方给出的文档,发现是因为序列化策略的问题。
这里简单说下:
SDR默认采用的序列化策略有两种,一种是String的序列化策略,一种是JDK的序列化策略。
StringRedisTemplate默认采用的是String的序列化策略,保存的key和value都是采用此策略序列化保存的。StringRedisSerializer
RedisTemplate默认采用的是JDK的序列化策略,保存的key和value都是采用此策略序列化保存的。JdkSerializationRedisSerializer
就是因为序列化策略的不同,即使是同一个key用不同的Template去序列化,结果是不同的。所以根据key去删除数据的时候就出现了删除失败的问题。
redisTemplate.opsForValue();//操作字符串
redisTemplate.opsForHash();//操作hash
redisTemplate.opsForList();//操作list
redisTemplate.opsForSet();//操作set
redisTemplate.opsForZSet();//操作有序set
Redis的String数据结构 (推荐使用StringRedisTemplate)
RedisSerializer<String> stringSerializer = new StringRedisSerializer();
template.setKeySerializer(stringSerializer );
template.setValueSerializer(stringSerializer );
template.setHashKeySerializer(stringSerializer );
template.setHashValueSerializer(stringSerializer );
那就先集成试一试咯,前提是你本地安装了redis
Maven
<!--redis集成-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
配置文件
application.properties
spring.redis.database=1
spring.redis.host=127.0.0.1
spring.redis.port=6379
spring.redis.password=123456
spring.redis.pool.max-idle=8
spring.redis.pool.min-idle=0
spring.redis.pool.max-active=8
spring.redis.pool.max-wait=-1
spring.redis.timeout=5000
Java代码
/**
* redis
* Created by gaomin on 2017/12/26.
*/
@Configuration
@EnableCaching
public class RedisCacheConfig {
@Value("${spring.redis.host}")
private String redisHost;
@Value("${spring.redis.port}")
private int redisPort;
@Value("${spring.redis.password}")
private String password;
@Bean
public RedisConnectionFactory redisCF(){
JedisConnectionFactory jcf=new JedisConnectionFactory();
jcf.setHostName(redisHost);
jcf.setPort(redisPort);
jcf.setPassword(password);
jcf.afterPropertiesSet();
jcf.setUsePool(true);
return jcf;
}
@Bean
public RedisTemplate redisTemplate(){
final RedisTemplate< String, Object > template = new RedisTemplate< String, Object >();
template.setKeySerializer(new StringRedisSerializer());//指定key的序列化
//template.setValueSerializer(new )
template.setConnectionFactory( redisCF() );
return template;
}
@Bean
public CacheManager cacheManager(){
return new RedisCacheManager(redisTemplate());
}
}
使用
@Override
public Object getDataByRedis() {
String key = RedisStaticUtil.MENUEXAMPLE_LIST;
List<Menu> menuList= (List<Menu>) redisTemplate.opsForValue().get(key);
if(menuList==null){
MenuExample menuExample = new MenuExample();
MenuExample.Criteria menuExampleCriteria = menuExample.createCriteria();
menuExampleCriteria.andStateEqualTo(0);
menuList = menuDao.selectByExample(menuExample);
redisTemplate.opsForValue().set(key,menuList);
}
return menuList;
}