1. 程式人生 > 實用技巧 >Redis批量查詢模板

Redis批量查詢模板

場景

在開發的時候經常會遇到批量取快取的問題,例如查詢商品資訊

  1. 傳入一個商品Id列表,查詢Redis資料存在則放入返回列表
  2. 不存在的資料查詢資料庫,並放入Redis
  3. 上面兩步資料整合返回

    虛擬碼為
	list.ForEach(str->{
dto = redis.get(str);
if(dto != null){
resultList.add(dto);
}else{
mustQuerySQL.add(str);
}
if(CollectionUtils.isNotEmpty(mustQuerySQL)){
querysqlList = querySQL(mustQuerySQL);
querySqlList.ForEach(dto->{
resultList.add(dto);
redis.put(dto);
})
}
})
return resultList;

問題是在專案中經常使用這樣的模式,有什麼辦法可以簡化步驟呢?

模板方法模式

模板方法模型是一種行為設計模型。模板方法是一個定義在父類別的方法,在模板方法中會呼叫多個定義在父類別的其他方法,而這些方法有可能只是抽象方法並沒有實作,模板方法僅決定這些抽象方法的執行順序,這些抽象方法的實作由子類別負責,並且子類別不允許覆寫模板方法。

我們可以使用模板方法模式,具體的從Redis中獲取資料以及SQL中獲取資料和SQL中資料放入Redis讓子類進行實現。

實現

程式碼如下:

public abstract class RedisUtil<T>  {

    public final List<T> getList(List<String> list){
List<T> resultList = new ArrayList<>();
List<String> mustQuery = new ArrayList<>();
list.forEach(str->{
T o = queryForRedis(str);
if(o != null){
resultList.add(o);
}else {
mustQuery.add(str);
}
});
if(CollectionUtils.isNotEmpty(mustQuery)) {
List<T> sql = queryForSQL(mustQuery);
sql.forEach(dto->{
setForRedis(dto);
resultList.add(dto);
});
}
return resultList;
} protected abstract T queryForRedis(String str); protected abstract List<T> queryForSQL(List<String> list); protected abstract void setForRedis(T t);
}

子類只需要使用匿名類即可實現,但是這樣在程式碼中會有這樣的程式碼

RedisUtil<String> redisUtil = new RedisUtil<String>() {
@Override
protected String queryForRedis(String str) {
return null;
} @Override
protected List<String> queryForSQL(List<String> list) {
return null;
} @Override
protected void setForRedis(String s) { }
};

佔據大量的程式碼段,看起來並不優雅,如何優雅的實現呢?

優化

//TODO