前言
- 經(jīng)常使用redis,固定前綴key每次都定義在當(dāng)前類下代乃,查詢或儲(chǔ)存redis時(shí)總是需要key+參數(shù)去操作旬牲,開發(fā)人員固守自封,后期維護(hù)成本加大搁吓,也看的不是很直觀原茅。
- 在最近的項(xiàng)目業(yè)務(wù)中,發(fā)現(xiàn)了比較好的處理方式堕仔,所以拿出來一起分享擂橘,當(dāng)然還有很多更加優(yōu)秀的方案,這里只是分享出來摩骨,供大家參考研究通贞。
- 說一下該方案大體的思路,通過定義公共key鍵值類仿吞,定義公共的查詢key鍵值方法滑频,來來統(tǒng)一管理,大大提升了代碼的通用性唤冈。
- 當(dāng)然峡迷,該方案思路不僅限于redis,可合理化的修改為自己想要的方案你虹,這里通過redis實(shí)例來進(jìn)行展示绘搞。
一、pom.xml文件
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-redis -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<version>2.6.2</version>
</dependency>
二傅物、key值公共管理類定義
/**
* 定義公共Key
*/
public interface RedisKey {
/**
* 公共頭部
*/
String KEY_REDIS = "wss:";
//樣例數(shù)據(jù)夯辖,可自行定義規(guī)則
interface childKey {
/**
* 用戶詳情請(qǐng)求 - 1
* 0 -> User.class
*/
String USER_KEY = "user:get:{0}";
/**
* 機(jī)構(gòu)詳情請(qǐng)求
* 0 -> 機(jī)構(gòu)ID
* 1 -> Org.class
*/
String ORG_KEY = "org:sev:{0}:{1}";
/**
* 用戶詳情請(qǐng)求 - 2
* 0 -> 用戶ID
* 1 -> 用戶名稱
* 2 -> 用戶年齡
*/
String USER_DETAIL_KEY = "user:get:{0}:{1}:{2}";
}
}
三、拼接key值類定義
import lombok.experimental.UtilityClass;
import org.springframework.lang.NonNull;
import java.text.MessageFormat;
/**
* 拼接key值
* @UtilityClass 相當(dāng)于每個(gè)方法都加了static
*/
@UtilityClass
public final class RedisKeyName {
private String key(@NonNull String key, Object... objs) {
return MessageFormat.format(RedisKey.KEY_REDIS + key, objs);
}
/**
* 通過用戶Id獲取用戶信息
*/
public String getUserKey(String userId) {
return key(RedisKey.childKey.USER_KEY, userId);
}
}
四董饰、獲取緩存類定義
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import java.util.Objects;
@Slf4j
@Component
@RequiredArgsConstructor
public class CacheService {
private final RedisTemplate<String, Object> redisTemplate;
/**
* 獲取緩存數(shù)據(jù)
**/
public <T> T getCacheByKey(String cacheKey, Class<T> clazz) {
Boolean b = redisTemplate.hasKey(cacheKey);
if (Objects.isNull(b) || Boolean.FALSE.equals(b)) {
return null;
}
try {
Object cacheObj = redisTemplate.opsForValue().get(cacheKey);
if (Objects.nonNull(cacheObj)) {
return clazz.cast(cacheObj);
}
} catch (Exception ignored) {
//如果反序列化拋錯(cuò)蒿褂,直接重取數(shù)據(jù)
}
return null;
}
}
五圆米、Controller定義 - 測(cè)試方法展示
import com.bi.my.util.CacheService;
import com.bi.my.util.RedisKeyName;
import org.apache.catalina.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.concurrent.TimeUnit;
/**
* 用戶管理
*/
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private CacheService cacheService;
@Autowired
private RedisTemplate<String, Object> redisTemplate;
/**
* 通過用戶id獲取用戶信息
*/
@GetMapping("getUser")
public void getUser(String userId) {
//通過用戶ID拼接對(duì)應(yīng)Key(最終返回userKey為 wss:user:get:userId)
String userKey = RedisKeyName.getUserKey(userId);
//存儲(chǔ)到redis中
redisTemplate.opsForValue().set(userKey, user, 300, TimeUnit.SECONDS);
//拿到key去redis查詢
User user = cacheService.getCacheByKey(userKey, User.class);
}
}