RedisTemplate集成+封裝RedisUtil過程
1.項目搭建
創(chuàng)建一個redis模塊

調(diào)整pom.xml,使其成為單獨的模塊
- sun-common-redis的pom.xml 取消parent

- sun-common的pom.xml 取消對redis模塊的管理

- sun-frame的pom.xml 增加對redis模塊的管理

關于只在modules中配置子模塊,但是子模塊沒有配置parent的用處
1. 多模塊項目的構建管理
使用標簽可以將多個子模塊組織在一個頂層的父項目中,從而實現(xiàn)以下幾個目標:
- a. 單點構建
- 你可以在父項目的根目錄下運行一次mvn install命令,就可以構建和安裝所有子模塊到本地Maven倉庫,而不需要分別進入每個子模塊目錄單獨運行構建命令。這大大簡化了多模塊項目的構建過程。
- b. 構建順序管理
- Maven會根據(jù)模塊間的依賴關系,自動確定各個模塊的構建順序,確保在構建一個模塊之前,先構建它所依賴的模塊。這在多模塊項目中是非常有用的,可以避免手動管理依賴順序的麻煩。
2. 統(tǒng)一的版本管理
即使子模塊沒有指定父項目,使用標簽仍然可以幫助你管理各個子模塊的版本一致性。你可以在父項目的POM文件中統(tǒng)一指定各個子模塊的版本號,然后在每個子模塊的POM文件中引用這個版本號。
3. 項目結構的組織和清晰度
將多個子模塊組織在一個父項目中,可以使項目結構更加清晰,便于管理。通過標簽,你可以一目了然地看到項目中包含哪些子模塊,以及它們之間的組織結構。
sun-common-redis引入redis依賴
<dependencies>
<!-- redis -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<version>2.4.2</version>
</dependency>
<!-- redis的pool -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
<version>2.9.0</version>
</dependency>
</dependencies>2.sun-user集成RedisTemplate
pom.xml引入sun-common-redis
<!-- 引入sun-common-redis -->
<dependency>
<groupId>com.sunxiansheng</groupId>
<artifactId>sun-common-redis</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>application.yml配置redis(集群模式)
spring:
# 配置redis(集群模式)
redis:
password: # Redis服務器密碼
database: 0 # 默認數(shù)據(jù)庫為0號
timeout: 10000ms # 連接超時時間是10000毫秒
lettuce:
pool:
max-active: 8 # 最大活躍連接數(shù),使用負值表示沒有限制,最佳配置為核數(shù)*2
max-wait: 10000ms # 最大等待時間,單位為毫秒,使用負值表示沒有限制,這里設置為10秒
max-idle: 200 # 最大空閑連接數(shù)
min-idle: 5 # 最小空閑連接數(shù)
cluster:
nodes:
TestController.java測試RedisTemplate
代碼
package com.sunxiansheng.user.controller;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
/**
* Description:
* @Author sun
* @Create 2024/7/8 17:55
* @Version 1.0
*/
@RestController
public class TestController {
@Resource
private RedisTemplate redisTemplate;
@RequestMapping("/testRedis")
public String testRedis() {
redisTemplate.opsForValue().set("name", "sunxiansheng");
return "Hello World!";
}
}訪問測試(發(fā)現(xiàn)有亂碼)

重寫RedisTemlate
引入Jackson的依賴
<!-- 重寫RedisTemlate需要的jackson序列化工具 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.8.5</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.11.4</version>
</dependency>
RedisConfig.java
package com.sunxiansheng.redis.config;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
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.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
/**
* Description: RedisConfig配置類
* @Author sun
* @Create 2024/7/19 11:11
* @Version 1.0
*/
@Configuration
public class RedisConfig {
/**
* 重寫RedisTemplate 解決亂碼問題
*
* @param redisConnectionFactory
* @return
*/
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory);
// key就使用redis提供的序列化RedisSerializer即可
RedisSerializer<String> redisSerializer = new StringRedisSerializer();
redisTemplate.setKeySerializer(redisSerializer);
redisTemplate.setHashKeySerializer(redisSerializer);
// value要使用Jackson的序列化
redisTemplate.setValueSerializer(jackson2JsonRedisSerializer());
redisTemplate.setValueSerializer(jackson2JsonRedisSerializer());
return redisTemplate;
}
/**
* 獲取一個Jackson的序列化對象邏輯
*
* @return
*/
private Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer() {
// 創(chuàng)建一個Jackson2JsonRedisSerializer對象,用于序列化和反序列化Java對象
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
// 創(chuàng)建一個ObjectMapper對象,用于JSON序列化和反序列化的配置
ObjectMapper objectMapper = new ObjectMapper();
// 設置ObjectMapper的可見性,使其可以訪問所有屬性
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
// 配置ObjectMapper,使其在遇到未知屬性時不會拋出異常
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
// 將配置好的ObjectMapper設置到Jackson2JsonRedisSerializer中
jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
// 返回配置好的Jackson2JsonRedisSerializer對象
return jackson2JsonRedisSerializer;
}
}
測試

3.封裝RedisUtil
RedisUtil.java
package com.sunxiansheng.redis.util;
import org.springframework.data.redis.core.Cursor;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ScanOptions;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* Description: RedisUtil工具類
* @Author sun
* @Create 2024/6/5 14:17
* @Version 1.0
*/
@Component
public class RedisUtil {
@Resource
private RedisTemplate redisTemplate;
private static final String CACHE_KEY_SEPARATOR = ".";
/**
* 構建緩存key
* @param strObjs 多個字符串拼接成緩存key
* @return 拼接后的緩存key
*/
public String buildKey(String... strObjs) {
return Stream.of(strObjs).collect(Collectors.joining(CACHE_KEY_SEPARATOR));
}
/**
* 是否存在key
* @param key Redis中的key
* @return true如果key存在,否則false
*/
public boolean exist(String key) {
return redisTemplate.hasKey(key);
}
/**
* 刪除key
* @param key Redis中的key
* @return true如果刪除成功,否則false
*/
public boolean del(String key) {
return redisTemplate.delete(key);
}
/**
* 設置key-value對
* @param key Redis中的key
* @param value 要設置的值
*/
public void set(String key, String value) {
redisTemplate.opsForValue().set(key, value);
}
/**
* 設置key-value對,如果key不存在,則設置成功,并指定過期時間
* @param key Redis中的key
* @param value 要設置的值
* @param time 過期時間
* @param timeUnit 時間單位
* @return true如果設置成功,否則false
*/
public boolean setNx(String key, String value, Long time, TimeUnit timeUnit) {
return redisTemplate.opsForValue().setIfAbsent(key, value, time, timeUnit);
}
/**
* 獲取指定key的值
* @param key Redis中的key
* @return key對應的值
*/
public String get(String key) {
return (String) redisTemplate.opsForValue().get(key);
}
/**
* 向有序集合中添加元素
* @param key Redis中的key
* @param value 元素的值
* @param score 元素的分數(shù)
* @return true如果添加成功,否則false
*/
public Boolean zAdd(String key, String value, Long score) {
return redisTemplate.opsForZSet().add(key, value, Double.valueOf(String.valueOf(score)));
}
/**
* 獲取有序集合的元素數(shù)量
* @param key Redis中的key
* @return 元素數(shù)量
*/
public Long countZset(String key) {
return redisTemplate.opsForZSet().size(key);
}
/**
* 獲取有序集合指定范圍內(nèi)的元素
* @param key Redis中的key
* @param start 起始位置
* @param end 結束位置
* @return 指定范圍內(nèi)的元素集合
*/
public Set<String> rangeZset(String key, long start, long end) {
return redisTemplate.opsForZSet().range(key, start, end);
}
/**
* 刪除有序集合中的指定元素
* @param key Redis中的key
* @param value 要刪除的元素
* @return 被刪除的元素數(shù)量
*/
public Long removeZset(String key, Object value) {
return redisTemplate.opsForZSet().remove(key, value);
}
/**
* 刪除有序集合中的多個元素
* @param key Redis中的key
* @param value 要刪除的元素集合
*/
public void removeZsetList(String key, Set<String> value) {
value.forEach(val -> redisTemplate.opsForZSet().remove(key, val));
}
/**
* 獲取有序集合中指定元素的分數(shù)
* @param key Redis中的key
* @param value 元素的值
* @return 元素的分數(shù)
*/
public Double score(String key, Object value) {
return redisTemplate.opsForZSet().score(key, value);
}
/**
* 獲取有序集合中指定分數(shù)范圍內(nèi)的元素
* @param key Redis中的key
* @param start 起始分數(shù)
* @param end 結束分數(shù)
* @return 指定分數(shù)范圍內(nèi)的元素集合
*/
public Set<String> rangeByScore(String key, long start, long end) {
return redisTemplate.opsForZSet().rangeByScore(key, Double.valueOf(String.valueOf(start)), Double.valueOf(String.valueOf(end)));
}
/**
* 增加有序集合中指定元素的分數(shù)
* @param key Redis中的key
* @param obj 元素的值
* @param score 增加的分數(shù)
* @return 增加后的分數(shù)
*/
public Object addScore(String key, Object obj, double score) {
return redisTemplate.opsForZSet().incrementScore(key, obj, score);
}
/**
* 獲取有序集合中指定元素的排名
* @param key Redis中的key
* @param obj 元素的值
* @return 元素的排名
*/
public Object rank(String key, Object obj) {
return redisTemplate.opsForZSet().rank(key, obj);
}
/**
* 從 Redis 有序集合(Sorted Set)中按分數(shù)范圍獲取成員及其分數(shù)
* @param key 排行榜的key
* @param start 起始位置(包含)
* @param end 結束位置(包含)
* @return Set<ZSetOperations.TypedTuple<String>> : 每個 TypedTuple 對象包含以下內(nèi)容:value: 集合中的成員,score: 成員的分數(shù)。
*/
public Set<ZSetOperations.TypedTuple<String>> rankWithScore(String key, long start, long end) {
return redisTemplate.opsForZSet().reverseRangeWithScores(key, start, end);
}
/**
* 向Redis中的hash結構存儲數(shù)據(jù)
* @param key 一個hash結構的key
* @param hashKey hash中的小key
* @param hashVal hash中的小value
*/
public void putHash(String key, String hashKey, Object hashVal) {
redisTemplate.opsForHash().put(key, hashKey, hashVal);
}
/**
* Redis中的String類型,獲取value時將其轉換為int類型
* @param key Redis中的key
* @return key對應的整數(shù)值
*/
public Integer getInt(String key) {
return (Integer) redisTemplate.opsForValue().get(key);
}
/**
* Redis中的String類型,將value增加一
* @param key Redis中的key
* @param count 增加的數(shù)量
*/
public void increment(String key, Integer count) {
redisTemplate.opsForValue().increment(key, count);
}
/**
* Redis中的hash類型,根據(jù)key來將每一個hashKey和hashValue轉換為Map類型
* @param key Redis中的hash結構的key
* @return Map<Object, Object> 包含hash結構中的所有鍵值對
*/
public Map<Object, Object> getHashAndDelete(String key) {
Map<Object, Object> map = new HashMap<>();
// 掃描hash,指定每一個Entry的類型,這里返回的就是Map的游標,可以進行遍歷
Cursor<Map.Entry<Object, Object>> cursor = redisTemplate.opsForHash().scan(key, ScanOptions.NONE);
// 遍歷每一條數(shù)據(jù),放到map中
while (cursor.hasNext()) {
Map.Entry<Object, Object> next = cursor.next();
Object hashKey = next.getKey();
Object hashValue = next.getValue();
map.put(hashKey, hashValue);
// 每遍歷一條就刪除
redisTemplate.opsForHash().delete(key, hashKey);
}
return map;
}
}總結
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
Redis緩存lettuce更換為Jedis的實現(xiàn)步驟
在springboot中引入spring-boot-starter-data-redis依賴時,默認使用的是lettuce,如果不想使用lettuce而是使用Jedis連接池,本文主要介紹了Redis緩存lettuce更換為Jedis的實現(xiàn)步驟,感興趣的可以了解一下2024-08-08
Redis 的查詢很快的原因解析及Redis 如何保證查詢的高效
由于redis是內(nèi)存數(shù)據(jù)庫,歸功于它的數(shù)據(jù)結構所以查詢效率非常高,今天通過本文給大家介紹下Redis 的查詢很快的原因解析及Redis 如何保證查詢的高效,感興趣的朋友一起看看吧2022-03-03
實現(xiàn)在線?+?離線模式進行遷移?Redis?數(shù)據(jù)實戰(zhàn)指南
這篇文章主要介紹了實現(xiàn)在線?+?離線模式進行遷移?Redis?數(shù)據(jù)實戰(zhàn)指南的相關資料,需要的朋友可以參考下2023-01-01

