IT评测·应用市场-qidao123.com技术社区

标题: 架构计划之自定义延迟双删缓存注解(下) [打印本页]

作者: 写过一篇    时间: 2025-3-26 06:17
标题: 架构计划之自定义延迟双删缓存注解(下)
架构计划之自定义延迟双删缓存注解(下)

小薛博客官方架构计划之自定义延迟双删缓存注解(下)所在
为了包管@Cache和@ClearAndReloadCache的灵活性,特意加入EL表达式剖析
1、Cache

  1. package com.xx.cache;
  2. import java.lang.annotation.*;
  3. import java.util.concurrent.TimeUnit;
  4. /**
  5. * @Author: xueqimiao
  6. * @Date: 2025/3/17 14:24
  7. */
  8. @Target(ElementType.METHOD)
  9. @Retention(RetentionPolicy.RUNTIME)
  10. @Documented
  11. public @interface Cache {
  12.     /**
  13.      * 过期时间,默认60s
  14.      * @return
  15.      */
  16.     long expire() default 60 ;
  17.     TimeUnit unit() default TimeUnit.SECONDS;
  18.     /**
  19.      * 缓存标识name
  20.      * @return
  21.      */
  22.     String name() default "";
  23.     /**
  24.      * SpringEL表达式,解析占位符对应的匹配value值
  25.      * @return
  26.      */
  27.     String matchValue();
  28. }
复制代码
2、CacheAspect

  1. package com.xx.cache;
  2. import com.xx.common.Result;
  3. import com.xx.utils.RedisService;
  4. import com.xx.utils.ValidationUtil;
  5. import jakarta.annotation.Resource;
  6. import lombok.extern.slf4j.Slf4j;
  7. import org.aspectj.lang.ProceedingJoinPoint;
  8. import org.aspectj.lang.annotation.Around;
  9. import org.aspectj.lang.annotation.Aspect;
  10. import org.aspectj.lang.annotation.Pointcut;
  11. import org.aspectj.lang.reflect.MethodSignature;
  12. import org.springframework.core.DefaultParameterNameDiscoverer;
  13. import org.springframework.expression.EvaluationContext;
  14. import org.springframework.expression.Expression;
  15. import org.springframework.expression.spel.standard.SpelExpressionParser;
  16. import org.springframework.expression.spel.support.StandardEvaluationContext;
  17. import org.springframework.stereotype.Component;
  18. import java.lang.reflect.Method;
  19. import java.util.concurrent.TimeUnit;
  20. /**
  21. * @Author: xueqimiao
  22. * @Date: 2025/3/17 14:25
  23. */
  24. @Component
  25. @Aspect
  26. @Slf4j
  27. public class CacheAspect {
  28.     @Resource
  29.     private RedisService redisService;
  30.     /**
  31.      * aop切点
  32.      * 拦截被指定注解修饰的方法
  33.      */
  34.     @Pointcut("@annotation(com.xx.cache.Cache)")
  35.     public void cache() {
  36.     }
  37.     /**
  38.      * 缓存操作
  39.      *
  40.      * @param pjp
  41.      * @return
  42.      */
  43.     @Around("cache()")
  44.     public Object toCache(ProceedingJoinPoint joinPoint) {
  45.         Object result = null;
  46.         try {
  47.             MethodSignature signature = (MethodSignature) joinPoint.getSignature();
  48.             Method method = joinPoint.getTarget().getClass().getMethod(signature.getName(),
  49.                     signature.getMethod().getParameterTypes());
  50.             Cache annotation = method.getAnnotation(Cache.class);
  51.             String matchedValue = annotation.matchValue();
  52.             String keyPrefix = annotation.name();
  53.             long time = annotation.expire();
  54.             TimeUnit unit = annotation.unit();
  55.             // 解析EL表达式
  56.             SpelExpressionParser parser = new SpelExpressionParser();
  57.             Expression expression = parser.parseExpression(matchedValue);
  58.             EvaluationContext context = new StandardEvaluationContext();
  59.             // 获取参数
  60.             Object[] args = joinPoint.getArgs();
  61.             DefaultParameterNameDiscoverer discoverer = new DefaultParameterNameDiscoverer();
  62.             String[] parameterNames = discoverer.getParameterNames(method);
  63.             for (int i = 0; i < parameterNames.length; i++) {
  64.                 context.setVariable(parameterNames[i], args[i]);
  65.             }
  66.             String key = keyPrefix + "::" + expression.getValue(context).toString();
  67.             result = redisService.get(key);
  68.             if (!ValidationUtil.isEmpty(result)) {
  69.                 return Result.ok(result);
  70.             }
  71.             // 执行目标方法
  72.             result = joinPoint.proceed();
  73.             Object res = result;
  74.             if (result instanceof Result) {
  75.                 res = ((Result<?>) result).getResult();
  76.             }
  77.             redisService.set(key, res, time, unit);
  78.         } catch (Throwable e) {
  79.             throw new RuntimeException(e);
  80.         }
  81.         return result;
  82.     }
  83. }
复制代码
3、ClearAndReloadCache

  1. package com.xx.cache;
  2. import java.lang.annotation.*;
  3. /**
  4. * @Author: xueqimiao
  5. * @Date: 2025/3/17 14:26
  6. */
  7. @Retention(RetentionPolicy.RUNTIME)
  8. @Documented
  9. @Target(ElementType.METHOD)
  10. public @interface ClearAndReloadCache {
  11.     /**
  12.      * 缓存标识name
  13.      * @return
  14.      */
  15.     String name() default "";
  16.     /**
  17.      * SpringEL表达式,解析占位符对应的匹配value值
  18.      * @return
  19.      */
  20.     String matchValue();
  21. }
复制代码
4、ClearAndReloadCacheAspect

  1. package com.xx.cache;
  2. import com.xx.utils.RedisUtils;
  3. import jakarta.annotation.Resource;
  4. import lombok.extern.slf4j.Slf4j;
  5. import org.aspectj.lang.ProceedingJoinPoint;
  6. import org.aspectj.lang.annotation.Around;
  7. import org.aspectj.lang.annotation.Aspect;
  8. import org.aspectj.lang.annotation.Pointcut;
  9. import org.aspectj.lang.reflect.MethodSignature;
  10. import org.springframework.core.DefaultParameterNameDiscoverer;
  11. import org.springframework.expression.EvaluationContext;
  12. import org.springframework.expression.Expression;
  13. import org.springframework.expression.spel.standard.SpelExpressionParser;
  14. import org.springframework.expression.spel.support.StandardEvaluationContext;
  15. import org.springframework.stereotype.Component;
  16. import java.lang.reflect.Method;
  17. /**
  18. * @Author: xueqimiao
  19. * @Date: 2025/3/17 14:26
  20. */
  21. @Aspect
  22. @Component
  23. @Slf4j
  24. public class ClearAndReloadCacheAspect {
  25.     @Resource
  26.     private RedisUtils redisUtils;
  27.     /**
  28.      * 切入点
  29.      * 切入点,基于注解实现的切入点  加上该注解的都是Aop切面的切入点
  30.      */
  31.     @Pointcut("@annotation(com.xx.cache.ClearAndReloadCache)")
  32.     public void pointCut() {
  33.     }
  34.     /**
  35.      * 环绕通知第一个参数必须是org.aspectj.lang.ProceedingJoinPoint类型
  36.      *
  37.      * @param proceedingJoinPoint
  38.      */
  39.     @Around("pointCut()")
  40.     public Object aroundAdvice(ProceedingJoinPoint joinPoint) {
  41.         log.info("----------- 环绕通知 -----------");
  42.         log.info("环绕通知的目标方法名:" + joinPoint.getSignature().getName());
  43.         try {
  44.             MethodSignature signature = (MethodSignature) joinPoint.getSignature();
  45.             Method method = joinPoint.getTarget().getClass().getMethod(signature.getName(),
  46.                     signature.getMethod().getParameterTypes());
  47.             ClearAndReloadCache annotation = method.getAnnotation(ClearAndReloadCache.class);//反射得到自定义注解的方法对象
  48.             String matchedValue = annotation.matchValue();
  49.             String keyPrefix = annotation.name(); //获取自定义注解的方法对象的参数即name
  50.             // 解析EL表达式
  51.             SpelExpressionParser parser = new SpelExpressionParser();
  52.             Expression expression = parser.parseExpression(matchedValue);
  53.             EvaluationContext context = new StandardEvaluationContext();
  54.             // 获取参数
  55.             Object[] args = joinPoint.getArgs();
  56.             DefaultParameterNameDiscoverer discoverer = new DefaultParameterNameDiscoverer();
  57.             String[] parameterNames = discoverer.getParameterNames(method);
  58.             for (int i = 0; i < parameterNames.length; i++) {
  59.                 context.setVariable(parameterNames[i], args[i]);
  60.             }
  61.             String key = keyPrefix + "::" + expression.getValue(context).toString();
  62.             redisUtils.del(key);//模糊删除redis的key值
  63.             //执行加入双删注解的改动数据库的业务 即controller中的方法业务
  64.             Object proceed = null;
  65.             try {
  66.                 proceed = joinPoint.proceed();//放行
  67.             } catch (Throwable throwable) {
  68.                 throwable.printStackTrace();
  69.             }
  70.             //新开开一个线程延迟0.5秒(时间可以改成自己的业务需求),等着mysql那边业务操作完成
  71.             //在线程中延迟删除  同时将业务代码的结果返回 这样不影响业务代码的执行
  72.             new Thread(() -> {
  73.                 try {
  74.                     Thread.sleep(500);
  75.                     redisUtils.del(key);
  76.                     log.info("-----------0.5秒后,在线程中延迟删除完毕 -----------");
  77.                 } catch (InterruptedException e) {
  78.                     e.printStackTrace();
  79.                 }
  80.             }).start();
  81.             return proceed;//返回业务代码的值
  82.         } catch (Throwable e) {
  83.             throw new RuntimeException(e);
  84.         }
  85.     }
  86. }
复制代码
5、UserController

  1. package com.xx.controller;
  2. import com.xx.cache.Cache;
  3. import com.xx.cache.ClearAndReloadCache;
  4. import com.xx.common.Result;
  5. import com.xx.entity.User;
  6. import com.xx.service.UserService;
  7. import jakarta.annotation.Resource;
  8. import org.springframework.web.bind.annotation.*;
  9. /**
  10. * @Author: xueqimiao
  11. * @Date: 2025/3/17 14:27
  12. */
  13. @RestController
  14. @RequestMapping("/user")
  15. public class UserController {
  16.     @Resource
  17.     private UserService userService;
  18.     @PostMapping("/updateData")
  19.     @ClearAndReloadCache(name = "user", matchValue = "#user.id")
  20.     public Result updateData(@RequestBody User user) {
  21.         return userService.update(user);
  22.     }
  23.     @GetMapping("/get")
  24.     @Cache(name = "user", matchValue = "#id")
  25.     public Result get(@RequestParam Integer id) {
  26.         return userService.get(id);
  27.     }
  28. }
复制代码
6、RedisService

  1. package com.xx.utils;
  2. import jakarta.annotation.Resource;
  3. import org.springframework.data.redis.core.*;
  4. import org.springframework.stereotype.Component;
  5. import java.io.Serializable;
  6. import java.util.*;
  7. import java.util.concurrent.TimeUnit;
  8. /**
  9. * @Author: xueqimiao
  10. * @Date: 2023/7/17 13:46
  11. */
  12. @Component
  13. public class RedisService {
  14.     @Resource
  15.     public RedisTemplate redisTemplate;
  16.     /**
  17.      * 默认过期时长,单位:秒 一天
  18.      */
  19.     public final static long DEFAULT_EXPIRE = 60 * 60 * 24;
  20.     /**
  21.      * 不设置过期时长
  22.      */
  23.     public final static long NOT_EXPIRE = -1;
  24.     private static double size = Math.pow(2, 32);
  25.     /*=======================================String - Object=======================================*/
  26.     /**
  27.      * 缓存基本的对象,Integer、String、实体类等
  28.      *
  29.      * @param key
  30.      * @param value
  31.      * @return
  32.      */
  33.     public boolean set(final String key, Object value) {
  34.         boolean result = false;
  35.         try {
  36.             ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
  37.             operations.set(key, value);
  38.             result = true;
  39.         } catch (Exception e) {
  40.             e.printStackTrace();
  41.         }
  42.         return result;
  43.     }
  44.     /**
  45.      * 写入缓存设置时效时间
  46.      *
  47.      * @param key
  48.      * @param value
  49.      * @return
  50.      */
  51.     public boolean set(final String key, Object value, Long expireTime) {
  52.         return set(key, value, expireTime, TimeUnit.SECONDS);
  53.     }
  54.     public boolean set(final String key, Object value, Long expireTime, TimeUnit unit) {
  55.         boolean result = false;
  56.         try {
  57.             ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
  58.             operations.set(key, value);
  59.             redisTemplate.expire(key, expireTime, unit);
  60.             result = true;
  61.         } catch (Exception e) {
  62.             e.printStackTrace();
  63.         }
  64.         return result;
  65.     }
  66.     public <T> void setCacheObject(final String key, final T value) {
  67.         redisTemplate.opsForValue().set(key, value);
  68.     }
  69.     /**
  70.      * 获得缓存的Object对象
  71.      *
  72.      * @param key 缓存的键值
  73.      * @return 缓存键值对应的数据
  74.      */
  75.     public Object getCache(final String key) {
  76.         return redisTemplate.opsForValue().get(key);
  77.     }
  78.     /**
  79.      * 获得缓存的基本对象。
  80.      *
  81.      * @param key 缓存键值
  82.      * @return 缓存键值对应的数据
  83.      */
  84.     public <T> T getCacheObject(final String key) {
  85.         ValueOperations<String, T> operation = redisTemplate.opsForValue();
  86.         return operation.get(key);
  87.     }
  88.     /**
  89.      * 获得缓存的基本对象。
  90.      *
  91.      * @param key 缓存键值
  92.      * @return 缓存键值对应的数据
  93.      */
  94.     public <T> T get(final String key) {
  95.         ValueOperations<String, T> operation = redisTemplate.opsForValue();
  96.         return operation.get(key);
  97.     }
  98.     /**
  99.      * 读取缓存
  100.      *
  101.      * @param key
  102.      * @return
  103.      */
  104.     public <T> T get(final String key, Class<T> clazz) {
  105.         ValueOperations<Serializable, Object> operation = redisTemplate.opsForValue();
  106.         T result = (T) operation.get(key);
  107.         return result;
  108.     }
  109.     /**
  110.      * 设置有效时间
  111.      *
  112.      * @param key     Redis键
  113.      * @param timeout 超时时间
  114.      * @return true=设置成功;false=设置失败
  115.      */
  116.     public boolean expire(final String key, final long timeout) {
  117.         return expire(key, timeout, TimeUnit.SECONDS);
  118.     }
  119.     /**
  120.      * 设置有效时间
  121.      *
  122.      * @param key     Redis键
  123.      * @param timeout 超时时间
  124.      * @param unit    时间单位
  125.      * @return true=设置成功;false=设置失败
  126.      */
  127.     public boolean expire(final String key, final long timeout, final TimeUnit unit) {
  128.         return redisTemplate.expire(key, timeout, unit);
  129.     }
  130.     /**
  131.      * 获取有效时间
  132.      *
  133.      * @param key Redis键
  134.      * @return 有效时间
  135.      */
  136.     public long getExpire(final String key) {
  137.         return redisTemplate.getExpire(key);
  138.     }
  139.     /**
  140.      * 判断 key是否存在
  141.      *
  142.      * @param key 键
  143.      * @return true 存在 false不存在
  144.      */
  145.     public Boolean hasKey(String key) {
  146.         return redisTemplate.hasKey(key);
  147.     }
  148.     /**
  149.      * 删除单个对象
  150.      *
  151.      * @param key
  152.      */
  153.     public void delete(String key) {
  154.         redisTemplate.delete(key);
  155.     }
  156.     /**
  157.      * 删除集合对象
  158.      *
  159.      * @param collection
  160.      */
  161.     public void delete(Collection collection) {
  162.         redisTemplate.delete(collection);
  163.     }
  164.     /**
  165.      * 判断缓存中是否有对应的value
  166.      *
  167.      * @param key
  168.      * @return
  169.      */
  170.     public boolean exists(final String key) {
  171.         return redisTemplate.hasKey(key);
  172.     }
  173.     /**
  174.      * 累加 1
  175.      *
  176.      * @param key 缓存的键值
  177.      * @return
  178.      */
  179.     public Long increment(final String key) {
  180.         return increment(key, 1L);
  181.     }
  182.     public Long decrement(final String key) {
  183.         return decrement(key, 1L);
  184.     }
  185.     /**
  186.      * 累加 指定值
  187.      *
  188.      * @param key 缓存的键值
  189.      * @param num 累加的数量
  190.      * @return
  191.      */
  192.     public Long increment(final String key, Long num) {
  193.         return redisTemplate.opsForValue().increment(key, num);
  194.     }
  195.     public Long decrement(final String key, Long num) {
  196.         return redisTemplate.opsForValue().decrement(key, num);
  197.     }
  198.     /**
  199.      * 获得缓存的基本对象key列表
  200.      *
  201.      * @param pattern 字符串前缀
  202.      * @return 对象列表
  203.      */
  204.     public Collection<String> keys(final String pattern) {
  205.         return redisTemplate.keys(pattern);
  206.     }
  207.     /*=======================================List=======================================*/
  208.     /**
  209.      * 缓存List数据
  210.      *
  211.      * @param key      缓存的键值
  212.      * @param dataList 待缓存的List数据
  213.      * @return 缓存的对象
  214.      */
  215.     public <T> long listRightPush(final String key, final List<T> dataList) {
  216.         Long count = redisTemplate.opsForList().rightPushAll(key, dataList);
  217.         return count == null ? 0 : count;
  218.     }
  219.     public long listRightPush(String key, String value) {
  220.         Long listSize = redisTemplate.opsForList().rightPush(key, value);
  221.         return null == listSize ? 0 : listSize;
  222.     }
  223.     public <T> long listLeftPush(final String key, final List<T> dataList) {
  224.         Long count = redisTemplate.opsForList().leftPushAll(key, dataList);
  225.         return count == null ? 0 : count;
  226.     }
  227.     public long listLeftPush(String key, String value) {
  228.         Long listSize = redisTemplate.opsForList().leftPush(key, value);
  229.         return null == listSize ? 0 : listSize;
  230.     }
  231.     public long listRemove(String key, long count, String value) {
  232.         Long remove = redisTemplate.opsForList().remove(key, count, value);
  233.         return null == remove ? 0 : remove;
  234.     }
  235.     /**
  236.      * 获得缓存的list对象
  237.      *
  238.      * @param key 缓存的键值
  239.      * @return 缓存键值对应的数据
  240.      */
  241.     public <T> List<T> getCacheList(final String key) {
  242.         return redisTemplate.opsForList().range(key, 0, -1);
  243.     }
  244.     /**
  245.      * 缓存List数据
  246.      *
  247.      * @param key      缓存的键值
  248.      * @param dataList 待缓存的List数据
  249.      * @return 缓存的对象
  250.      */
  251.     public <T> long setCacheList(final String key, final List<T> dataList) {
  252.         Long count = redisTemplate.opsForList().rightPushAll(key, dataList);
  253.         return count == null ? 0 : count;
  254.     }
  255.     /**
  256.      * 列表获取
  257.      *
  258.      * @param k
  259.      * @param start
  260.      * @param end
  261.      * @return
  262.      */
  263.     public <T> List<T> listRange(String k, long start, long end) {
  264.         ListOperations<String, T> list = redisTemplate.opsForList();
  265.         return list.range(k, start, end);
  266.     }
  267.     public <T> List<T> listRange(String k) {
  268.         return listRange(k, 0, -1);
  269.     }
  270.     /*=======================================Set=======================================*/
  271.     /**
  272.      * 缓存Set
  273.      *
  274.      * @param key     缓存键值
  275.      * @param dataSet 缓存的数据
  276.      * @return 缓存数据的对象
  277.      */
  278.     public <T> BoundSetOperations<String, T> setCacheSet(final String key, final Set<T> dataSet) {
  279.         BoundSetOperations<String, T> setOperation = redisTemplate.boundSetOps(key);
  280.         Iterator<T> it = dataSet.iterator();
  281.         while (it.hasNext()) {
  282.             setOperation.add(it.next());
  283.         }
  284.         return setOperation;
  285.     }
  286.     /**
  287.      * 获得缓存的set
  288.      *
  289.      * @param key
  290.      * @return
  291.      */
  292.     public <T> Set<T> getCacheSet(final String key) {
  293.         return redisTemplate.opsForSet().members(key);
  294.     }
  295.     /**
  296.      * 集合添加
  297.      *
  298.      * @param key
  299.      * @param value
  300.      */
  301.     public void add(String key, Object value) {
  302.         SetOperations<String, Object> set = redisTemplate.opsForSet();
  303.         set.add(key, value);
  304.     }
  305.     /**
  306.      * 集合获取
  307.      *
  308.      * @param key
  309.      * @return
  310.      */
  311.     public Set<Object> setMembers(String key) {
  312.         SetOperations<String, Object> set = redisTemplate.opsForSet();
  313.         return set.members(key);
  314.     }
  315.     public <T> T pop(String key) {
  316.         SetOperations<String, T> set = redisTemplate.opsForSet();
  317.         return set.pop(key);
  318.     }
  319.     public <T> List<T> pop(String key, Long num) {
  320.         SetOperations<String, T> set = redisTemplate.opsForSet();
  321.         return set.pop(key, num);
  322.     }
  323.     /*=======================================ZSet=======================================*/
  324.     /**
  325.      * 有序集合添加
  326.      *
  327.      * @param key
  328.      * @param value
  329.      * @param scoure
  330.      */
  331.     public void zAdd(String key, Object value, double scoure) {
  332.         ZSetOperations<String, Object> zset = redisTemplate.opsForZSet();
  333.         zset.add(key, value, scoure);
  334.     }
  335.     /**
  336.      * 有序集合获取
  337.      *
  338.      * @param key
  339.      * @param scoure
  340.      * @param scoure1
  341.      * @return
  342.      */
  343.     public Set<Object> rangeByScore(String key, double scoure, double scoure1) {
  344.         ZSetOperations<String, Object> zset = redisTemplate.opsForZSet();
  345.         redisTemplate.opsForValue();
  346.         return zset.rangeByScore(key, scoure, scoure1);
  347.     }
  348.     /**
  349.      * 有序集合获取排名
  350.      *
  351.      * @param key   集合名称
  352.      * @param value 值
  353.      */
  354.     public Long zRank(String key, Object value) {
  355.         ZSetOperations<String, Object> zset = redisTemplate.opsForZSet();
  356.         return zset.rank(key, value);
  357.     }
  358.     /**
  359.      * 有序集合获取排名
  360.      *
  361.      * @param key
  362.      */
  363.     public Set<ZSetOperations.TypedTuple<Object>> zRankWithScore(String key, long start, long end) {
  364.         ZSetOperations<String, Object> zset = redisTemplate.opsForZSet();
  365.         Set<ZSetOperations.TypedTuple<Object>> ret = zset.rangeWithScores(key, start, end);
  366.         return ret;
  367.     }
  368.     /**
  369.      * 有序集合添加
  370.      *
  371.      * @param key
  372.      * @param value
  373.      */
  374.     public Double zSetScore(String key, Object value) {
  375.         ZSetOperations<String, Object> zset = redisTemplate.opsForZSet();
  376.         return zset.score(key, value);
  377.     }
  378.     /**
  379.      * 有序集合添加分数
  380.      *
  381.      * @param key
  382.      * @param value
  383.      * @param scoure
  384.      */
  385.     public void incrementScore(String key, Object value, double scoure) {
  386.         ZSetOperations<String, Object> zset = redisTemplate.opsForZSet();
  387.         zset.incrementScore(key, value, scoure);
  388.     }
  389.     /**
  390.      * 有序集合获取排名
  391.      *
  392.      * @param key
  393.      */
  394.     public Set<ZSetOperations.TypedTuple<Object>> reverseZRankWithScore(String key, long start, long end) {
  395.         ZSetOperations<String, Object> zset = redisTemplate.opsForZSet();
  396.         Set<ZSetOperations.TypedTuple<Object>> ret = zset.reverseRangeByScoreWithScores(key, start, end);
  397.         return ret;
  398.     }
  399.     /**
  400.      * 有序集合获取排名
  401.      *
  402.      * @param key
  403.      */
  404.     public Set<ZSetOperations.TypedTuple<Object>> reverseZRankWithRank(String key, long start, long end) {
  405.         ZSetOperations<String, Object> zset = redisTemplate.opsForZSet();
  406.         Set<ZSetOperations.TypedTuple<Object>> ret = zset.reverseRangeWithScores(key, start, end);
  407.         return ret;
  408.     }
  409.     /*=======================================Hash=======================================*/
  410.     /**
  411.      * 缓存Map
  412.      *
  413.      * @param key
  414.      * @param dataMap
  415.      */
  416.     public <T> void setCacheMap(final String key, final Map<String, T> dataMap) {
  417.         if (dataMap != null) {
  418.             redisTemplate.opsForHash().putAll(key, dataMap);
  419.         }
  420.     }
  421.     /**
  422.      * 获得缓存的Map
  423.      *
  424.      * @param key
  425.      * @return
  426.      */
  427.     public <T> Map<String, T> getCacheMap(final String key) {
  428.         return redisTemplate.opsForHash().entries(key);
  429.     }
  430.     /**
  431.      * 往Hash中存入数据
  432.      *
  433.      * @param key   Redis键
  434.      * @param hKey  Hash键
  435.      * @param value 值
  436.      */
  437.     public <T> void setCacheMapValue(final String key, final String hKey, final T value) {
  438.         redisTemplate.opsForHash().put(key, hKey, value);
  439.     }
  440.     /**
  441.      * 获取Hash中的数据
  442.      *
  443.      * @param key  Redis键
  444.      * @param hKey Hash键
  445.      * @return Hash中的对象
  446.      */
  447.     public <T> T getCacheMapValue(final String key, final String hKey) {
  448.         HashOperations<String, String, T> opsForHash = redisTemplate.opsForHash();
  449.         return opsForHash.get(key, hKey);
  450.     }
  451.     /**
  452.      * 获取多个Hash中的数据
  453.      *
  454.      * @param key   Redis键
  455.      * @param hKeys Hash键集合
  456.      * @return Hash对象集合
  457.      */
  458.     public <T> List<T> getMultiCacheMapValue(final String key, final Collection<Object> hKeys) {
  459.         return redisTemplate.opsForHash().multiGet(key, hKeys);
  460.     }
  461.     /**
  462.      * 哈希 添加
  463.      *
  464.      * @param key
  465.      * @param hashKey
  466.      * @param value
  467.      */
  468.     public void hmSet(String key, Object hashKey, Object value) {
  469.         HashOperations<String, Object, Object> hash = redisTemplate.opsForHash();
  470.         hash.put(key, hashKey, value);
  471.     }
  472.     /**
  473.      * 哈希获取数据
  474.      *
  475.      * @param key
  476.      * @param hashKey
  477.      * @return
  478.      */
  479.     public Object hmGet(String key, Object hashKey) {
  480.         HashOperations<String, Object, Object> hash = redisTemplate.opsForHash();
  481.         return hash.get(key, hashKey);
  482.     }
  483.     /*=======================================Bit=======================================*/
  484.     /**
  485.      * 写入缓存
  486.      *
  487.      * @param key
  488.      * @param offset 位 8Bit=1Byte
  489.      * @return
  490.      */
  491.     public boolean setBit(String key, long offset, boolean isShow) {
  492.         boolean result = false;
  493.         try {
  494.             ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
  495.             operations.setBit(key, offset, isShow);
  496.             result = true;
  497.         } catch (Exception e) {
  498.             e.printStackTrace();
  499.         }
  500.         return result;
  501.     }
  502.     /**
  503.      * 写入缓存
  504.      *
  505.      * @param key
  506.      * @param offset
  507.      * @return
  508.      */
  509.     public boolean getBit(String key, long offset) {
  510.         boolean result = false;
  511.         try {
  512.             ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
  513.             result = operations.getBit(key, offset);
  514.         } catch (Exception e) {
  515.             e.printStackTrace();
  516.         }
  517.         return result;
  518.     }
  519.     public void saveDataToRedis(String name) {
  520.         Double index = Math.abs(name.hashCode() % size);
  521.         long indexLong = index.longValue();
  522.         boolean availableUsers = setBit("availableUsers", indexLong, true);
  523.     }
  524.     public boolean getDataToRedis(String name) {
  525.         Double index = Math.abs(name.hashCode() % size);
  526.         long indexLong = index.longValue();
  527.         return getBit("availableUsers", indexLong);
  528.     }
  529. }
复制代码
博客心语

在Java编程的征程中,我们都是追梦人。每一次编写代码,都是在编织一个关于未来的故事。这个故事可能是一个高效的电商系统,让购物变得更加便捷;也可能是一个智能的医疗应用,拯救无数的生命。无论你的目标是什么,Java都是你实现空想的有力武器。以是,不要停下你前进的脚步,不断探索Java的深度和广度,让你的代码充满生命力,由于你正在用一种巨大的语言塑造着一个充满无限可能的未来。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 IT评测·应用市场-qidao123.com技术社区 (https://dis.qidao123.com/) Powered by Discuz! X3.4