RedisTemplate和StringRedisTemplate的系列文章詳見:
Spring Boot(十七):集成和使用Redis
Spring Boot(十八):RedisTemplate和StringRedisTemplate
Spring Boot(十九):StringRedisTemplate的常用方法和注意事項
Spring Boot(二十):RedisTemplate的序列化
RedisTemplate支持Redis提供的所有數據類型(包括String、Hash、List、Set和ZSet等),并提供靈活的配置選項和事務支持,方便開發者與Redis交互。
String類型操作
如果鍵和值都是String類型,推薦使用StringRedisTemplate來操作,StringRedisTemplate的各種方法,詳見Spring Boot(十九),下面我們來簡單介紹兩個Spring Boot(十九)中沒有涉及的方法
?1、opsForValue().increment?
方法簽名:
Long increment(K key):默認加1,返回遞增后的新值,可直接用于業務判斷
Long increment(K key, long num):如果num為正數,則值加num,如果num為負數,則值減num,返回遞增后的新值,可直接用于業務判斷
示例:
try {stringRedisTemplate.opsForValue().set("name:number", "12345");log.info("name:number, {}", stringRedisTemplate.opsForValue().get("name:number"));Long num = stringRedisTemplate.opsForValue().increment("name:number");log.info("name:number increment加1, {}", num);num = stringRedisTemplate.opsForValue().increment("name:number", 10);log.info("name:number increment加10, {}", num);num = stringRedisTemplate.opsForValue().increment("name:number", -10);log.info("name:number increment減10, {}", num);
} catch (Exception e) {log.info("name:number increment error, {}", e.toString());
}
2、opsForValue().decrement
方法簽名:
Long decrement(K key):默認減1,返回遞減后的新值,可直接用于業務判斷
Long decrement(K key, long num):如果num為正數,則值減num,如果num為負數,則值加num,返回遞減后的新值,可直接用于業務判斷
3、使用場景
increment的使用場景:
1)獨立計數器:用于統計訪問量、點贊數、下載量等
2)限流:限制接口的訪問頻率,如每秒最多允許訪問100次
3)唯一ID生成:生成全局唯一的遞增ID
4)分布式計數器:跟蹤分布式系統中待處理任務的數量
decrement的使用場景:
1)庫存管理:用于減少商品庫存
2)名額限制:優惠券剩余數量、報名人數統計
3)余額減少:在金融系統中減少賬戶余額
4)限流:減少允許的訪問次數
5)分布式計數器:跟蹤分布式系統中待處理任務的數量
4、注意
1)值的類型必須為整數
使用increment或decrement方法時,如值為整數類型(如String類型的"123"),則會正常的增減,若值為字符串(比如"value"),則會報如下錯誤:
org.springframework.data.redis.RedisSystemException: Error in execution; nested exception is io.lettuce.core.RedisCommandExecutionException: ERR value is not an integer or out of range
2)序列化問題
如果使用的是RedisTemplate,需要確保值的序列化器為StringRedisSerializer,在Spring Boot(二十)中我們把RedisTemplate的值的序列化方式改?為了Jackson2JsonRedisSerializer,?所以如果直接使用redisTemplate.opsForValue().increment會報錯,因為這時值為Json格式,值不能直接自增或自減,報錯如下:
org.springframework.data.redis.RedisSystemException: Error in execution; nested exception is io.lettuce.core.RedisCommandExecutionException: ERR value is not an integer or out of range
3)初始值
執行increment和decrement時,如果鍵不存在,Redis會將其值初始化為0,然后執行自增/自減操作
4)原子性
increment和decrement操作是原子性的,保證在高并發場景下的數據一致性
Hash類型操作
RedisTemplate對Redis中的Hash類型提供了多種操作方法,?通過opsForHash(),?可以進行Hash的增刪查操作。
1、基本操作
Hash類型適合存儲多字段對象或需要頻繁更新部分字段的數據,下面我們通過用戶信息存儲來說明一下Hash類型的操作:
// 存儲用戶信息
redisTemplate.opsForHash().put("user:1001", "name", "Alice");
redisTemplate.opsForHash().put("user:1001", "age", "29");
redisTemplate.opsForHash().put("user:1001", "email", "alice@test.com");// 獲取單個字段
String name = redisTemplate.opsForHash().get("user:1001", "name").toString();
log.info("user:1001 name, {}", name);// 獲取所有字段
Map<String, Object> user = redisTemplate.opsForHash().entries("user:1001");
user.forEach((key, value) -> {log.info("key:{}, value:{}", key, value.toString());
});
還可以使用另外一種方式存儲用戶信息:
Map<String, String> userMap = new HashMap<>();
userMap.put("name", "Rabbit");
userMap.put("age", "3");
userMap.put("email", "rabbit@test.com");
redisTemplate.opsForHash().putAll("user:1002", userMap);
使用Hash類型,更新某屬性的值時非常方便:
// 更新年齡
redisTemplate.opsForHash().put("user:1001", "age", "30");
int age = Integer.parseInt(redisTemplate.opsForHash().get("user:1001", "age").toString());
log.info("user:1001 age, {}", age);
刪除某個屬性:
// 刪除用戶的某個屬性
redisTemplate.opsForHash().delete("user:1001", "email");
2、適用場景
Hash類型適合存儲多字段對象或需要頻繁更新部分字段的數據,包括但不限于以下場景:
1)用戶信息存儲
存儲用戶詳細信息,如姓名、年齡、郵箱等
2)購物車管理
電商系統中,用Hash存儲用戶購物車中的商品及其數量
3)配置管理
集中管理應用配置參數,
4)統計字段聚合
用戶行為的多維度統計,如點贊數、收藏數等
5)對象緩存
緩存數據庫查詢結果(如商品詳情、訂單信息等),減少數據庫壓力
6)分布式Session存儲
在集群環境中,用Hash存儲用戶會話信息(如登錄狀態、權限)
3、注意
1)避免將Hash用于字段數量巨大(如百萬級)的場景,可能引發性能問題