一、Redis簡介
Redis是NoSql(非關係型數據庫)中的一種,是C語言開發的一個高性能鍵值數據庫,即通過一些鍵值類型來存儲數據。Redis的鍵值類型有:String字符類型、map散列類型、list列表類型、set集合類型、sortedset有序集合類型。
Redis適用場景:秒殺庫存覈減,常用訪問數據量高的相對固定數據,分佈式集羣架構中的session分離,聊天室的好友列表,任務隊列等。
Redis 優勢:(1)性能極高 , Redis能讀的速度是110000次/s,寫的速度是81000次/s;(2)豐富的數據類型; (3)Redis的所有操作都是原子性的,同時Redis還支持對幾個操作全並後的原子性執行;(4) Redis還支持 publish/subscribe, 通知, key 過期等等特性。
Redis的詳細介紹、配置及命令可以參考官方文檔:https://www.redis.net.cn/tutorial/3504.html
Linux下的Redis安裝可以參考:Linux服務器搭建——Redis的安裝
Windows下的Redis安裝:
(1)下載Windows版本Redis:https://github.com/MSOpenTech/redis/releases,下載最新的windows X64版本的壓縮包(選擇.zip)
(2)下載之後解壓redis,在redis目錄打開cmd,啓動redis:redis-server.exe redis.windows.conf
(PS:此處指定了配置文件:redis.windows.conf。打開該文件可修改配置。常見的配置修改是將bind 127.0.0.1和requirepass foobared,這兩行註釋掉,即在前面加上#)
二、SpringBoots整合Redis
在SpringBoot中一般使用RedisTemplate提供的方法來操作Redis。
(1)首先搭建一個Springboot項目,注意依賴中引入包的版本,我直接用的spring initial搭的項目。
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.2.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
(2)引入redis的依賴:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<version>2.2.0.RELEASE</version>
</dependency>
Redis自1.4.7之後,依賴包已經改成spring-boot-starter-data-redis了。這個依賴中集成了一些redis需要的配置(比如工廠模型JedisConnectionFactory、JredisConnectionFactory、LettuceConnectionFactory、SrpConnectionFactory),不需要自己再配置RedisConfig類(但是如果不滿足自己需要,也可以重寫,可以參考以下兩篇博文:
SpringBoot整合Redis及Redis工具類撰寫)。引入包版本不正確會導致類找不到等系列問題。
(3)在application.properties中添加redis的相關配置
# Redis數據庫索引(默認爲0)
spring.redis.database=0
# Redis服務器地址
spring.redis.host=127.0.0.1
# Redis服務器連接端口
spring.redis.port=6379
# Redis服務器連接密碼(默認爲空)
spring.redis.password=
# 連接池最大連接數(使用負值表示沒有限制)
#spring.redis.pool.max-active=200
spring.redis.jedis.pool.max-active=200
# 連接池最大阻塞等待時間(使用負值表示沒有限制)
#spring.redis.pool.max-wait=-1
spring.redis.jedis.pool.max-wait=-1ms
# 連接池中的最大空閒連接
#spring.redis.pool.max-idle=10
spring.redis.jedis.pool.max-idle=10
# 連接池中的最小空閒連接
#spring.redis.pool.min-idle=0
spring.redis.jedis.pool.min-idle=0
# 連接超時時間(毫秒)
spring.redis.timeout=1000ms
(4)測試
操作完以上三步就可以直接注入RedisTemplate來操作redis了,這裏我是將RedisTemplate的一些方法全都封裝進了RedisUtil,直接使用注入的redisUtil進行的測試。另外我也重新寫了RedisConfig。
RedisConfig:
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
/**
* redis配置
* @author zhangy
* @date 2020-03-25 18:29
* @version 1.0
**/
@Configuration
@EnableCaching //開啓註解
public class RedisConfig extends CachingConfigurerSupport {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory){
RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
template.setConnectionFactory(factory);
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
// key採用String的序列化方式
template.setKeySerializer(stringRedisSerializer);
// hash的key也採用String的序列化方式
template.setHashKeySerializer(stringRedisSerializer);
// value序列化方式採用jackson
template.setValueSerializer(jackson2JsonRedisSerializer);
// hash的value序列化方式採用jackson
template.setHashValueSerializer(jackson2JsonRedisSerializer);
template.afterPropertiesSet();
return template;
}
}
RedisUtil:(只貼了格式爲String的部分方法,還有hash、set等的數據類型可以自己繼續完善)
@Component
public class RedisUtil {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
/**
* 指定緩存失效時間
* @param key
* @param time
* @return
*/
public boolean expire(String key, long time){
try {
if(time > 0){
redisTemplate.expire(key, time, TimeUnit.SECONDS);
}
return true;
}catch (Exception e){
e.printStackTrace();
return false;
}
}
/**
* 根據key獲取過期時間
* @param key
* @return
*/
public long getExipire(String key){
return redisTemplate.getExpire(key, TimeUnit.SECONDS);
}
/**
* 判斷key是否存在
* @param key
* @return
*/
public boolean hasKey(String key){
try{
return redisTemplate.hasKey(key);
}catch (Exception e){
e.printStackTrace();
return false;
}
}
/**
* 刪除緩存
* @param key 可以傳一個或多個
*/
public void del(String ...key){
if (key != null && key.length > 0){
if(key.length == 1){
redisTemplate.delete(key[0]);
}else{
redisTemplate.delete(CollectionUtils.arrayToList(key));
}
}
}
/**
* 普通緩存獲取
* @param key
* @return
*/
public Object get(String key){
return key == null?null:redisTemplate.opsForValue().get(key);
}
/**
* 普通緩存放入
* @param key
* @param value
* @return
*/
public boolean set(String key, Object value){
try{
redisTemplate.opsForValue().set(key, value);
return true;
}catch (Exception e){
e.printStackTrace();
return false;
}
}
}
測試用例直接貼代碼:
參考了很多文章,也是以上面幾個步驟爲主,但是我操作完執行項目的時候遇到了很多問題(當時沒有截圖記錄,不能提供具體的異常信息,還請將就!):
1、啓動時報錯:
Caused by: org.springframework.beans.factory.support.BeanDefinitionOverrideException: Invalid bean definition with name 'stringRedisTemplate' defined in class path resource
這是由於我自己實現了RedisConfig,但是注入的bean的名稱不正確,此處的方法名爲redisTemplate纔可以覆蓋spring-boot-starter-data-redis中自動配置的redisTemplate(詳細解釋可以參考:SpringBoot整合Redis及Redis工具類撰寫)。(此處RedisConfig繼承了CachingConfigurerSupport,沒有太多必要,可以不用繼承)
2、啓動時報錯:
'org.springframework.data.redis.connection.RedisConnectionFactory' that could not be found.
這個問題困擾了我兩天,一直沒有解決,後來發現還是redis包依賴的問題。(其實一開始也發現,但是依賴一直沒有引對,也有可能是別的一些依賴有影響)所以pom中引入依賴的時候一定要注意版本號(可參考:springboot+redis項目實戰)。(如果想查看工程用的包所依賴的包的版本可以去http://mvnrepository.com/輸入對應的包如spring-data-redis)
3、連接不上redis:
ERR Client sent AUTH, but no password is set
這個就是上面提到的redis的配置問題了,註釋掉相應的配置就可以了。
(有些問題可能也是我誤打誤撞解決了,有不足的地方還請指出)
項目工程:https://github.com/CoolITDog/test-redis.git