RedisUtil:
/**
* 批量查询缓存,若是缓存没有的数据再调用对应的方法查询数据,查询之后放入缓存
* @param prefix 缓存前缀
* @param params 缓存参数
* @param column 缓存参数对应字段列名
* @param dataBaseFunction 数据库查询方法
* @return
* @param <T> 查询参数
* @param <R> 返回类型
*/
public <T,R> List<R> batchGetCacheData(String prefix, Collection<T> params, String column,
Function<Set<T>,List<R>> dataBaseFunction, Class<R> clazz){
// TODO 未大规模测试 暂时不使用
// 先查redis
Set<String> keys = params.stream().map(m -> {return prefix + m;}).collect(Collectors.toSet());
List<String> cacheResultList = new ArrayList<>();
List<List<T>> splitList = ListUtil.split((Collection<T>) keys, 500);
for (List<T> ts : splitList) {
cacheResultList.addAll(redisTemplate.executePipelined(new RedisCallback<String>() {
@Override
public String doInRedis(RedisConnection connection) throws DataAccessException {
for (T key : ts) {
connection.get(key.toString().getBytes());
}
return null;
}
}));
}
//过滤出没有获取到缓存的数据,去执行对应数据库查询
Tuple2<Set<T>, List<R>> tuple2 = analysisCacheVal(params, cacheResultList, clazz);
Set<T> queryKeys = tuple2.getFirst();
List<R> result = tuple2.getSecond();
if(!CollectionUtils.isEmpty(result) && result.size() == params.size()){
return result;
}
List<R> dataBaseResult = getDataBaseFunction(prefix, queryKeys, dataBaseFunction, column);
result.addAll(dataBaseResult);
return result;
}
private static <T,R> Tuple2<Set<T>, List<R>> analysisCacheVal (Collection<T> params, List<String> cacheResultList, Class<R> clazz) {
Set<T> queryKeys = new HashSet<>();
List<R> result = new ArrayList<>();
T[] paramsObj = (T[]) params.toArray();
for (int i = 0; i< params.size(); i++) {
String cacheR = cacheResultList.get(i);
if (Objects.isNull(cacheR)) {
queryKeys.add(paramsObj[i]);
} else {
result.add(JSON.parseObject(cacheR, clazz));
}
}
return new Tuple2<>(queryKeys, result);
}
private <T,R> List<R> getDataBaseFunction (String prefix, Set<T> queryKeys, Function<Set<T>,List<R>> dataBaseFunction, String column) {
List<R> dataBaseResult = dataBaseFunction.apply(queryKeys);
if(!CollectionUtils.isEmpty(dataBaseResult)){
for (R r : dataBaseResult) {
Object obj = getProperty(r, column);
if (Objects.nonNull(obj)) {
redisTemplate.opsForValue().set(prefix + obj.toString(), JSON.toJSONString(r), 1, TimeUnit.MINUTES);
}
}
}
return dataBaseResult;
}
public static <R> Object getProperty(R object, String column) {
Class<?> clazz = object.getClass();
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
if (field.getName().equals(column)) {
try {
field.setAccessible(true);
return field.get(object);
} catch (IllegalAccessException e) {
log.error("RedisUtil getProperty error {}", e);
return null;
}
}
}
return null;
}
调用方式:redisUtil.batchGetCacheData("country:", ids, "id", v -> countryBiz.getByIds(ids), CountryVO.class);
ListUtil
public static final int DEFAULT_LIMIT = 500;
public static final int LIMIT1000 = 1000;
public static <T> List<List<T>> split(Collection<T> collection) {
return split(collection, DEFAULT_LIMIT);
}
public static <T> List<List<T>> split(Collection<T> collection, int size) {
if (collection == null || collection.isEmpty()) {
return Collections.emptyList();
}
List<T> list = new ArrayList<>(collection);
final int listSize = list.size();
final List<List<T>> result = new ArrayList<>(listSize / size + 1);
int offset = 0;
for (int toIdx = size; toIdx <= listSize; offset = toIdx, toIdx += size) {
result.add(list.subList(offset, toIdx));
}
if (offset < listSize) {
result.add(list.subList(offset, listSize));
}
return result;
}
标签:再查,缓存,return,redis,List,params,result,queryKeys,先查
From: https://blog.51cto.com/u_13643129/7483558