Redis 簡介redis
REmote DIctionary ServerRedisRedis 是一個由Salvatore Sanfilippo寫的key-value存儲系統。Redis是一個開源的spring
使用ANSI C語言編寫、遵照BSD協議、支持網絡、可基於內存亦可持久化的日誌型、Key-Value數據庫,並提供多種語言的API。它通數據庫
常被稱爲數據結構服務器,由於值(value)能夠是 字符串(String), 哈希(Map), 列表(list), 集合(sets) 和 有序集合服務器
(sorted sets)等類型。網絡
Redis 優點
數據結構
性能極高 – Redis能讀的速度是110000次/s,寫的速度是81000次/s 。
app
豐富的數據類型 – Redis支持二進制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 數據類型操做。
ide
原子 – Redis的全部操做都是原子性的,意思就是要麼成功執行要麼失敗徹底不執行。單個操做是原子性的。多個操做也支持事務,即原子性,
spring-boot
經過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中定義了對5種數據結構操做
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; }