• redis批量先查缓存再查数据库


     

    1. /**
    2. * 批量查询缓存,若是缓存没有的数据再调用对应的方法查询数据,查询之后放入缓存
    3. * @param prefix 缓存前缀
    4. * @param params 缓存参数
    5. * @param column 缓存参数对应字段列名
    6. * @param dataBaseFunction 数据库查询方法
    7. * @return
    8. * @param 查询参数
    9. * @param 返回类型
    10. */
    11. public List batchGetCacheData(String prefix, Collection params, String column,
    12. Function,List> dataBaseFunction, Class clazz){
    13. // TODO 未大规模测试 谨慎使用
    14. // 先查redis
    15. Set keys = params.stream().map(m -> {return prefix + m;}).collect(Collectors.toSet());
    16. List cacheResultList = new ArrayList<>();
    17. List> splitList = ListUtil.split((Collection) keys, 500);
    18. for (List ts : splitList) {
    19. cacheResultList.addAll(redisTemplate.executePipelined(new RedisCallback() {
    20. @Override
    21. public String doInRedis(RedisConnection connection) throws DataAccessException {
    22. for (T key : ts) {
    23. connection.get(key.toString().getBytes());
    24. }
    25. return null;
    26. }
    27. }));
    28. }
    29. //过滤出没有获取到缓存的数据,去执行对应数据库查询
    30. Tuple2, List> tuple2 = analysisCacheVal(params, cacheResultList, clazz);
    31. Set queryKeys = tuple2.getFirst();
    32. List result = tuple2.getSecond();
    33. if(!CollectionUtils.isEmpty(result) && result.size() == params.size()){
    34. return result;
    35. }
    36. List dataBaseResult = getDataBaseFunction(prefix, queryKeys, dataBaseFunction, column);
    37. result.addAll(dataBaseResult);
    38. return result;
    39. }
    40. private static Tuple2, List> analysisCacheVal (Collection params, List cacheResultList, Class clazz) {
    41. Set queryKeys = new HashSet<>();
    42. List result = new ArrayList<>();
    43. T[] paramsObj = (T[]) params.toArray();
    44. for (int i = 0; i< params.size(); i++) {
    45. String cacheR = cacheResultList.get(i);
    46. if (Objects.isNull(cacheR)) {
    47. queryKeys.add(paramsObj[i]);
    48. } else {
    49. result.add(JSON.parseObject(cacheR, clazz));
    50. }
    51. }
    52. return new Tuple2<>(queryKeys, result);
    53. }
    54. private List getDataBaseFunction (String prefix, Set queryKeys, Function,List> dataBaseFunction, String column) {
    55. List dataBaseResult = dataBaseFunction.apply(queryKeys);
    56. if(!CollectionUtils.isEmpty(dataBaseResult)){
    57. for (R r : dataBaseResult) {
    58. Object obj = getProperty(r, column);
    59. if (Objects.nonNull(obj)) {
    60. redisTemplate.opsForValue().set(prefix + obj.toString(), JSON.toJSONString(r), 1, TimeUnit.MINUTES);
    61. }
    62. }
    63. }
    64. return dataBaseResult;
    65. }
    66. public static Object getProperty(R object, String column) {
    67. Class clazz = object.getClass();
    68. Field[] fields = clazz.getDeclaredFields();
    69. for (Field field : fields) {
    70. if (field.getName().equals(column)) {
    71. try {
    72. field.setAccessible(true);
    73. return field.get(object);
    74. } catch (IllegalAccessException e) {
    75. log.error("RedisUtil getProperty error {}", e);
    76. return null;
    77. }
    78. }
    79. }
    80. return null;
    81. }

    使用方式

    redisUtil.batchGetCacheData("country:", ids, "id", v -> baseMapper.getByIds(ids), 查询对象.class);

    1. public class ListUtil {
    2. public static final int DEFAULT_LIMIT = 500;
    3. public static final int LIMIT1000 = 1000;
    4. public static List> split(Collection collection) {
    5. return split(collection, DEFAULT_LIMIT);
    6. }
    7. public static List> split(Collection collection, int size) {
    8. if (collection == null || collection.isEmpty()) {
    9. return Collections.emptyList();
    10. }
    11. List list = new ArrayList<>(collection);
    12. final int listSize = list.size();
    13. final List> result = new ArrayList<>(listSize / size + 1);
    14. int offset = 0;
    15. for (int toIdx = size; toIdx <= listSize; offset = toIdx, toIdx += size) {
    16. result.add(list.subList(offset, toIdx));
    17. }
    18. if (offset < listSize) {
    19. result.add(list.subList(offset, listSize));
    20. }
    21. return result;
    22. }
    23. }

  • 相关阅读:
    【数据标注】Label Studio用于机器学习标注
    C++之map如何实例化类对象(一百九十九)
    tiobe的内容项怎么回事?
    2019CCPC网络赛 杭电 6705 path(题解+代码)
    day2-web安全漏洞攻防-基础-弱口令、HTML注入(米斯特web渗透测试)
    openssl3.2 - note - Writing OpenSSL Provider Skeleton
    [ffmpeg系列] 从应用的角度学习ffmpeg
    使用windows端MySQL创建数据库
    jsp 技术
    LDO(线性稳压器)设计检查
  • 原文地址:https://blog.csdn.net/eternity_zzy/article/details/132906544