一、理論基礎
1.1 redis是什么
- redis是一種key-value的數(shù)據庫,數(shù)據緩存在內存中,也可以持久化到硬盤
- 一種遠程字典服務
- 高性能、單線程的NoSQL數(shù)據庫
- 支持的數(shù)據類型
- String
- List
- Set
- zSet(有序集合)
- hash
1.2 redis可以做什么
- 最常用的功能是緩存,將頻繁訪問的資源提前緩存到內存中加快訪問速度,減少網絡、IO等損耗
- 可用做簡易版的消息隊列
- redis是單線程的,可以用作計數(shù)器,比如接口訪問次數(shù)等
- ……
二、實戰(zhàn)代碼
2.1 依賴引入
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- lettuce pool 緩存連接池 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
<version>2.8.0</version>
</dependency>
2.2 配置文件
spring:
application:
name: spring-boot-redis-demo
redis:
host: 127.0.0.1
port: 6379
# redis數(shù)據庫索引
database: 10
password: 123456
lettuce:
pool:
max-active: 10
# 連接池最大阻塞等待時間(使用負值表示沒有限制)
max-wait: 3000
# 連接池中的最大空閑連接
max-idle: 5
# 連接池中的最小空閑連接
min-idle: 2
# 超時時間(毫秒)
timeout: 10000
2.3 配置類
/**
* Redis配置
* @author smile
*/
@Configuration
public class RedisConfig {
@Resource
private LettuceConnectionFactory connectionFactory;
@Bean
public RedisTemplate<String, Object> redisTemplate() {
connectionFactory.setShareNativeConnection(false);
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
// 視使用情況配置,配置json,則獲取的值只能是JSON格式的
redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
redisTemplate.setConnectionFactory(connectionFactory);
return redisTemplate;
}
@Bean
public HashOperations<String, String, Object> hashOperations(RedisTemplate<String, Object> redisTemplate) {
return redisTemplate.opsForHash();
}
@Bean
public ValueOperations<String, Object> valueOperations(RedisTemplate<String, Object> redisTemplate) {
return redisTemplate.opsForValue();
}
@Bean
public ListOperations<String, Object> listOperations(RedisTemplate<String, Object> redisTemplate) {
return redisTemplate.opsForList();
}
@Bean
public SetOperations<String, Object> setOperations(RedisTemplate<String, Object> redisTemplate) {
return redisTemplate.opsForSet();
}
@Bean
public ZSetOperations<String, Object> zSetOperations(RedisTemplate<String, Object> redisTemplate) {
return redisTemplate.opsForZSet();
}
}
2.4 示例代碼
2.4.1 StringRedisTemplate
StringRedisTemplate是Springboot Redis已經封裝好的一個工具類,支持key、value都是String的數(shù)據結構存儲。可滿足基本的場景
// 注入
@Autowired
private StringRedisTemplate redisTemplate;
public void aa() {
redisTemplate.opsForValue().set("testSpringbootRedis", "這里可以寫各種字符串的值");
redisTemplate.opsForValue().increment("aaa");
}
2.4.2 RedisTemplate示例代碼
@Component
public class RedisCommonUtils {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
/**
* 設置緩存失效時間
* @param key 鍵
* @param time 過期時間(單位:秒) 如果不大于0則會馬上過期
* @return 成功返回true
*/
public boolean expire(String key,long time){
return redisTemplate.expire(key, Duration.ofSeconds(time));
}
/**
* 獲取過期時間
* @param key 鍵 不能為null
* @return 時間(秒)
*/
public long getExpire(String key){
return redisTemplate.getExpire(key, TimeUnit.SECONDS);
}
/**
* 判斷key是否存在
* @param key 鍵
* @return true-存在 false-不存在
*/
public boolean hasKey(String key){
return redisTemplate.hasKey(key);
}
/**
* 刪除緩存
* @param key 待刪除鍵
*/
public void del(String key){
redisTemplate.delete(key);
}
/**
* 刪除多個key
* @param keys 待刪除的鍵
*/
public void delKeys(List<String> keys) {
redisTemplate.delete(keys);
}
}
2.4.3 ValueOperations示例代碼
public class RedisValueUtils {
@Autowired
private ValueOperations<String, Object> valueOperations;
/**
* 讀取
* @param key 鍵
* @return 值
*/
public Object get(String key){
return valueOperations.get(key);
}
/**
* 設置普通緩存
* @param key 鍵
* @param value 值
*/
public void set(String key, Object value) {
valueOperations.set(key, value);
}
/**
* 帶過期時間的緩存
* @param key 鍵
* @param value 值
* @param time 過期時間(單位:秒),過期時間必須大于0
*/
public void set(String key, Object value, long time){
if (time > 0) {
valueOperations.set(key, value, Duration.ofSeconds(time));
}else {
throw new RuntimeException("過期時間必須大于0");
}
}
/**
* 計數(shù)器-遞增,每次+1
* @param key 鍵
* @return 自增操作后的值
*/
public long incr(String key){
return valueOperations.increment(key);
}
/**
* 計數(shù)器-遞增
* @param key 鍵
* @param delta 每次遞增的值
* @return 遞增操作后的值
*/
public long incr(String key, long delta){
if(delta > 0){
return valueOperations.increment(key, delta);
}
throw new RuntimeException("遞增因子必須大于0");
}
/**
* 遞減
* @param key 鍵
* @return 操作后的值
*/
public long decr(String key){
return valueOperations.decrement(key);
}
/**
* 遞減
* @param key 鍵
* @param delta 每次減少的值
* @return 操作后的值
*/
public long decr(String key, long delta){
if(delta > 0){
valueOperations.decrement(key, delta);
}
throw new RuntimeException("遞減因子必須大于0");
}
}
2.4.5 scan掃描多個Key
public void scan2(String matchKey) {
Set<String> keys = new HashSet<>();
ScanOptions options = ScanOptions.scanOptions().match(matchKey).count(1000)
.build();
Cursor<String> cursor = (Cursor<String>) redisTemplate.executeWithStickyConnection(
redisConnection -> {
return new ConvertingCursor<>(redisConnection.scan(options),
redisTemplate.getKeySerializer()::deserialize);
});
cursor.forEachRemaining(key -> {
keys.add(key);
System.out.println(key);
});
}
2.4.6 SessionCallBack 使用一個連接操作多次
redisTemplate.execute(new SessionCallback<Object>() {
@Override
public Object execute(RedisOperations redisOperations) throws DataAccessException {
redisOperations.opsForList().leftPush(REDIS_KEY_LATEST_DATA,
CommonGenerator.createData("19.01", "energy-electric"));
return null;
}
});
2.4.7 其他示例見GitHub
https://github.com/lysmile/spring-boot-demo/tree/master/spring-boot-redis-demo